#更新履歴
2017/11/11 :初版
2017/11/11 18:17 : interfaceクラスの属性と操作の可視性、および操作の定義を出力しないように修正
2017/11/11 19:32 : クラスの属性をフィールドではなくプロパティとして出力するように変更
#はじめに
前回のUMLモデリングツールastah*(Community版)でプラグイン開発環境を試してみた(2)では、Consoleにクラスの各種情報を書き出しましたが、今回は、それらの情報でC#のコードを出力してみたいと思います。
astah*には、any というコード生成プラグインがあるのですが、community6.9では使えないため、community6.9でも使えるものをと、コードを書いてみました。
#ご注意とお願い
パーフェクトにコンパイルに通るほどではないですが、VisualStudioで読み込んで、赤い波線を自分では確認できなかった程度になっています。プラグインのコードをそのまま載せるので、さらに改造してみるのであれば、どうぞ。
今のところ、流れのままに作ったので、クラス分割もしていません。
また、私の環境だと、日本語コメントを入れると、ビルドエラーになってしまうため、分かりやすいコメントが入っていません。Javaは普段使っていないので、ちょっとだけググったのですが解決できず、誰か教えてくれると助かります。
自分で使うために作ったので、不具合や改善があれば、この記事を更新します。
#対応したC#コード出力機能
- クラス
- 可視性、abstract、クラス名、テンプレート、ベースクラス、実現するインタフェース
- 関連(可視性、関連の型、関連端名、多重度によるList表現)
- 属性(可視性、属性の型、属性名、初期値、=new )
- 操作(抽象、可視性、操作名、引数、引数の型、out、ref 、操作の定義、戻り値の型)
- インタフェースクラス
- 属性 -> プロパティとして出力
- 操作 -> 戻り値、操作名、引数、引数の型、out、ref)
※ 「操作の戻り値」と「操作の引数」の型がListの場合は、astah*に情報が見つからず(入力する欄もないので、たぶんないと思われる)、対応できませんでした。コード出力後に手作業で直してください。
#プラグインのコード
前回、前々回の記事に引き続き、PrintClassAction.cs というファイルのみ変更していますので、
そのファイルの中身を下記に置換してください。
package com.azuki.actions;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import com.change_vision.jude.api.inf.AstahAPI;
import com.change_vision.jude.api.inf.exception.ProjectNotFoundException;
import com.change_vision.jude.api.inf.model.IClass;
import com.change_vision.jude.api.inf.model.IModel;
import com.change_vision.jude.api.inf.model.IAttribute;
import com.change_vision.jude.api.inf.model.IMultiplicityRange;
import com.change_vision.jude.api.inf.model.IOperation;
import com.change_vision.jude.api.inf.model.IGeneralization;
import com.change_vision.jude.api.inf.model.INamedElement;
import com.change_vision.jude.api.inf.model.ITemplateBinding;
import com.change_vision.jude.api.inf.model.IClassifierTemplateParameter;
import com.change_vision.jude.api.inf.model.IRealization;
import com.change_vision.jude.api.inf.model.IParameter;
import com.change_vision.jude.api.inf.model.IPackage;
import com.change_vision.jude.api.inf.project.ProjectAccessor;
import com.change_vision.jude.api.inf.ui.IPluginActionDelegate;
import com.change_vision.jude.api.inf.ui.IWindow;
import java.io.File;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.IOException;
public class PrintClassAction implements IPluginActionDelegate
{
public Object run(IWindow window) throws UnExpectedException
{
try {
AstahAPI api = AstahAPI.getAstahAPI();
ProjectAccessor projectAccessor = api.getProjectAccessor();
IModel iCurrentProject = projectAccessor.getProject();
List<IClass> classeList = new ArrayList<IClass>();
getAllClasses(iCurrentProject, classeList);
// changed code from here.
System.out.println("[Output follow files]");
for (IClass c : classeList)
{
List<String> classCode = MakeClassCode(c); // make 1 class code string
WriteCSFile(getClassTypeName(c), classCode); // write file
PrintList(classCode); // output to console
}
System.out.println("... are created.");
// changed code to here.
} catch (ProjectNotFoundException e) {
String message = "Please open a project";
JOptionPane.showMessageDialog(window.getParent(), message,
"Warning", JOptionPane.WARNING_MESSAGE);
throw new CalculateUnExpectedException();
} catch (Exception e) {
JOptionPane.showMessageDialog(window.getParent(),
"Exception occured", "Alert", JOptionPane.ERROR_MESSAGE);
throw new UnExpectedException();
}
return null;
}
public class CalculateUnExpectedException extends UnExpectedException
{
}
private void getAllClasses(INamedElement element, List<IClass> classList)
throws ClassNotFoundException, ProjectNotFoundException {
if (element instanceof IPackage) {
for(INamedElement ownedNamedElement : ((IPackage) element).getOwnedElements()) {
getAllClasses(ownedNamedElement, classList);
}
} else if (element instanceof IClass) {
classList.add((IClass) element);
}
}
// My Methods
private String getClassTypeName(IClass _class)
{
return _class.getName();
}
private String getClassOption(IClass _class)
{
StringBuilder buff = new StringBuilder();
if (_class.isAbstract() == true) { buff.append("abstract "); }
if (_class.isPublicVisibility() == true) { buff.append("public "); }
if (_class.isPackageVisibility() == true) { buff.append("internal "); }
if (_class.isProtectedVisibility() == true) { buff.append("C# class can not to be protected. "); }
if (_class.isPrivateVisibility() == true) { buff.append("C# class can not to be private. "); }
return buff.toString();
}
private boolean isInterface(IClass _class)
{
return _class.hasStereotype("interface");
}
private boolean isCSharpPrimitiveType(String typeName)
{
if (typeName.equals("byte") == true)
{
return true;
}
else if (typeName.equals("Byte") == true)
{
return true;
}
else if (typeName.equals("sbyte") == true)
{
return true;
}
else if (typeName.equals("SByte") == true)
{
return true;
}
else if (typeName.equals("int") == true)
{
return true;
}
else if (typeName.equals("Int32") == true)
{
return true;
}
else if (typeName.equals("uint") == true)
{
return true;
}
else if (typeName.equals("UInt32") == true)
{
return true;
}
else if (typeName.equals("short") == true)
{
return true;
}
else if (typeName.equals("Int16") == true)
{
return true;
}
else if (typeName.equals("ushort") == true)
{
return true;
}
else if (typeName.equals("UInt16") == true)
{
return true;
}
else if (typeName.equals("long") == true)
{
return true;
}
else if (typeName.equals("Int64") == true)
{
return true;
}
else if (typeName.equals("ulong") == true)
{
return true;
}
else if (typeName.equals("UInt64") == true)
{
return true;
}
else if (typeName.equals("float") == true)
{
return true;
}
else if (typeName.equals("Single") == true)
{
return true;
}
else if (typeName.equals("double") == true)
{
return true;
}
else if (typeName.equals("Double") == true)
{
return true;
}
else if (typeName.equals("char") == true)
{
return true;
}
else if (typeName.equals("Char") == true)
{
return true;
}
else if (typeName.equals("bool") == true)
{
return true;
}
else if (typeName.equals("Boolean") == true)
{
return true;
}
else
{
return false;
}
}
private String getTemplateParameter(IClass _class)
{
StringBuilder buff = new StringBuilder();
IClassifierTemplateParameter[] ctemps = _class.getTemplateParameters();
if (ctemps.length > 0) { buff.append("<"); }
for (int i = 0; i < ctemps.length; i++)
{
buff.append(ctemps[i].getName());
if (i < ctemps.length - 1) { buff.append(","); }
}
if (ctemps.length > 0) { buff.append(">"); }
return buff.toString();
}
private boolean getClassIsActive(IClass _class)
{
return _class.isActive();
}
private String getClassDefinition(IClass _class)
{
return _class.getDefinition();
}
private String getBaseClassName(IClass _class)
{
StringBuilder buff = new StringBuilder();
IGeneralization[] gens = _class.getGeneralizations();
for (int i = 0; i < gens.length; i++)
{
buff.append(gens[i].getSuperType().getName() + " ");
if (i < gens.length - 1)
{
buff.append(" , ");
}
}
return buff.toString();
}
private String getInterfaceClassName(IClass _class)
{
StringBuilder buff = new StringBuilder();
IRealization[] ifs = _class.getClientRealizations();
for (int i = 0; i < ifs.length; i++)
{
buff.append(ifs[i].getSupplier().getName() + " ");
if (i < ifs.length - 1)
{
buff.append(" , ");
}
}
return buff.toString();
}
private IAttribute[] getAssociations(IClass _class)
{
IAttribute[] atts = _class.getAttributes();
int count = 0;
for (int i = 0; i < atts.length; i++)
{
if (atts[i].getAssociation() != null)
{
count++;
}
}
IAttribute data[] = new IAttribute[count];
int add = 0;
for (int i = 0; i < atts.length; i++)
{
if (atts[i].getAssociation() != null)
{
data[add++] = atts[i];
}
}
return data;
}
private IAttribute[] getAttributes(IClass _class)
{
IAttribute[] atts = _class.getAttributes();
int count = 0;
for (int i = 0; i < atts.length; i++)
{
if (atts[i].getAssociation() == null)
{
count++;
}
}
IAttribute data[] = new IAttribute[count];
int add = 0;
for (int i = 0; i < atts.length; i++)
{
if (atts[i].getAssociation() == null)
{
data[add++] = atts[i];
}
}
return data;
}
private String getAssociation(IAttribute _att)
{
if (_att.getAssociation() != null)
{
if (_att.getName().equals("") == true)
{
System.out.println("no association end name , so not make code for type " + _att.getType() + ".");
return "";
}
StringBuilder buff = new StringBuilder();
buff.append(getAttributeOption(_att));
boolean isList = isList(_att);
if (isList == true) { buff.append("List<"); }
buff.append(_att.getType() + " ");
if (isList == true) { buff.append("> "); }
buff.append(_att.getName() + " ");
buff.append(";");
return buff.toString();
}
return "";
}
private String getAttribute(IAttribute _att, boolean isInterface)
{
if (_att.getAssociation() == null)
{
// create attribute type and name
StringBuilder type = new StringBuilder();
boolean isList = isList(_att);
if (isList == true) { type.append("List<"); }
String cSharpTypeName = convertJavaTypeToCSharpType(_att.getType().getName());
type.append(cSharpTypeName + " ");
if (isList == true) { type.append("> "); }
String typeString = type.toString();
String localmark = "_";
StringBuilder buff = new StringBuilder();
if( isInterface == false ){
// class
// private attribute
if( _att.isStatic() == true ){
buff.append("static ");
}
buff.append("private " + typeString + " " + localmark + _att.getName() );
// initialize for private attribute
String initval = _att.getInitialValue();
if (isCSharpPrimitiveType(cSharpTypeName) == false)
{
buff.append(" = new " + cSharpTypeName + "(");
if (initval.equals("") != true)
{
buff.append(initval);
}
buff.append(")");
}
else
{
if (initval.equals("") != true)
{
buff.append(" = " + initval);
}
}
buff.append(";");
buff.append("\r\n");
buff.append("\t" + getAttributeOption(_att) + typeString + " " + _att.getName());
buff.append("\r\n\t{");
if( _att.isStatic() == false ){
buff.append("\r\n\t\tset { " + localmark + _att.getName() + " = value; }");
}
buff.append("\r\n\t\tget { return " + localmark + _att.getName() + "; }");
buff.append("\r\n\t}");
} else {
// interface
buff.append(typeString + " " + _att.getName());
buff.append(" { set; get; } ");
}
return buff.toString();
}
return "";
}
private boolean isList(IAttribute _att)
{
boolean _list = false;
IMultiplicityRange[] multis = _att.getMultiplicity();
for (int i = 0; i < multis.length; i++) // fukusuu aru ?
{
if (multis[i].getUpper() > 1)
{
_list = true;
}
}
return _list;
}
private String getAttributeOption(IAttribute _att)
{
StringBuilder buff = new StringBuilder();
if (_att.isStatic() == true) { buff.append("static "); }
if (_att.isPublicVisibility() == true) { buff.append("public "); }
if (_att.isPackageVisibility() == true) { buff.append("internal "); }
if (_att.isProtectedVisibility() == true) { buff.append("protected "); }
if (_att.isPrivateVisibility() == true) { buff.append("private "); }
return buff.toString();
}
public String getOperation(IOperation _ope, boolean isInterface)
{
StringBuilder buff = new StringBuilder();
if( isInterface == false ){
buff.append(getOpearationOption(_ope));
}
buff.append(_ope.getReturnTypeExpression() + " ");
buff.append(_ope.getName() + "(");
buff.append(getOperationAttributes(_ope) + ")");
if( isInterface == true ){
buff.append(";");
}
return buff.toString();
}
public String getOperationDefinition(IOperation _ope)
{
StringBuilder buff = new StringBuilder();
String str = _ope.getDefinition();
// str.replaceAll("\n", "\r\n");
String[] lines = str.split("\n");
for (String line : lines)
{
buff.append("\r\n\t\t" + line );
}
buff.append("\r\n");
return buff.toString();
}
private String getOpearationOption(IOperation _ope)
{
StringBuilder buff = new StringBuilder();
if (_ope.isStatic() == true) { buff.append("static "); }
if (_ope.isAbstract() == true) { buff.append("abstract "); }
if (_ope.isPublicVisibility() == true) { buff.append("public "); }
if (_ope.isPackageVisibility() == true) { buff.append("internal "); }
if (_ope.isProtectedVisibility() == true) { buff.append("protected "); }
if (_ope.isPrivateVisibility() == true) { buff.append("private "); }
return buff.toString();
}
private String convertJavaTypeToCSharpType(String _typeName)
{
String typeName = _typeName;
if (typeName.equals("boolean") == true)
{
typeName = "Boolean";
}
return typeName;
}
private String getOperationAttributes(IOperation _ope)
{
StringBuilder buff = new StringBuilder();
IParameter[] params = _ope.getParameters();
for (int i = 0; i < params.length; i++ ){
if ( params[i].getDirection().equals("out") == true ){ buff.append("out "); } else if( params[i].getDirection().equals("inout") == true ){ buff.append("ref "); }
buff.append(convertJavaTypeToCSharpType( params[i].getType().getName() ) + " ");
buff.append(params[i].getName());
if(i< params.length-1 ){
buff.append(" , ");
}
}
return buff.toString();
}
/* create c# code */
private List<String> MakeClassCode(IClass _class)
{
boolean isInterface = isInterface(_class);
List<String> CodeList = new ArrayList<String>();
CodeList.add(MakeUsing());
CodeList.add(MakeClassDef(_class));
IAttribute[] assos = getAssociations(_class);
CodeList.add("\r\n\t// Associations");
for (int i = 0; i < assos.length; i++)
{
String asscode = getAssociation(assos[i]);
if (asscode.equals("") == false)
{
CodeList.add("\t" + asscode);
}
}
IAttribute[] atts = getAttributes(_class);
CodeList.add("\r\n\t// Attributes");
for (int i = 0; i < atts.length; i++)
{
CodeList.add("\t" + getAttribute(atts[i],isInterface));
CodeList.add("");
}
IOperation[] opes = _class.getOperations();
CodeList.add("\r\n\t// Operations");
for (int i = 0; i < opes.length; i++)
{
CodeList.add("\t" + getOperation(opes[i],isInterface));
if( isInterface == false ){
// class
CodeList.add("\t{" + getOperationDefinition(opes[i]) + "\r\n\t}");
} else {
// interface
}
CodeList.add("");
}
CodeList.add("}\r\n");
return CodeList;
}
private String MakeUsing()
{
StringBuilder buff = new StringBuilder();
buff.append("using System;\r\n");
buff.append("using System.Collections;\r\n");
buff.append("using System.Collections.Generic;\r\n");
buff.append("using System.Linq;\r\n");
buff.append("using System.Text;\r\n");
return buff.toString();
}
private String MakeClassDef(IClass _class)
{
StringBuilder buff = new StringBuilder();
buff.append(getClassOption(_class));
if (isInterface(_class) == true)
{
buff.append("interface ");
}
else
{
buff.append("class ");
}
buff.append(getClassTypeName(_class));
buff.append(getTemplateParameter(_class));
String baseClassName = getBaseClassName(_class);
String interfaceClassName = getInterfaceClassName(_class);
if (baseClassName.equals("") == false)
{
buff.append(" : ");
buff.append(baseClassName);
if (interfaceClassName.equals("") == false)
{
buff.append(",");
buff.append(interfaceClassName);
}
}
else if (interfaceClassName.equals("") == false)
{
buff.append(" : ");
buff.append(",");
buff.append(interfaceClassName);
}
buff.append(" {");
return buff.toString();
}
/* file output */
private void WriteCSFile(String className, List<String> contents)
{
try
{
String filePath = "c:/tmp/" + className + ".cs";
System.out.println(filePath);
File file = new File(filePath);
try
{
file.createNewFile();
}
catch (IOException e)
{
System.out.println(e);
}
if (checkWritefile(file))
{
PrintWriter pwriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));
for (String linedata : contents)
{
pwriter.println(linedata);
}
pwriter.close();
}
else
{
System.out.println("Can not write in file.");
}
}
catch (IOException e)
{
System.out.println(e);
}
}
private static boolean checkWritefile(File file)
{
if (file.exists())
{
if (file.isFile() && file.canWrite())
{
return true;
}
}
return false;
}
private void PrintList(List<String> datalist)
{
for (String linedata : datalist)
{
System.out.println(linedata);
}
}
}
#出力されたC#コードの様子
#さいごに
このC#コード出力は、しっかりと考えて作っていないので、変なコード出力が残っていると思います。
もし、使ってみた人がいれば、報告お願いいたします。
もう一つ、大切なことを忘れていました。
当方、Javaのエンジニアではないので、ググりながらコードを書きました。まずいJavaコードが混じっていたら、教えてください。よろしくお願いいたします。