やる気を阻害するもの

PCがすぐ落ちる・・・
昔も書いたのですが解決はしていなかったり。


子供がうるさい


嫁が週末くらいは相手しろ・・・と
まぁ至極もっともなお話です・・・


というのはさておき

	/**
	 * 元情報を、画面VOに移し変える。
	 * Templateで調整がきかないような場合、ここで調整する。
	 * @param orig 元のClassObject
	 * @return 画面VO用ClassObject
	 */
	public static final ClassObject convertForFormVO(final ClassObject orig) {
		ClassObject result = new ClassObject();
		result.setClassName(orig.getClassName() + "FormVO");
		result.setPackageStr(orig.getPackageStr());
		
		ArrayList<FieldVO> list = new ArrayList<FieldVO>();
		final FieldVO[] properties = orig.getProperties();
		for (int i = 0; i < properties.length; i++) {
			FieldVO vo = new FieldVO();
			vo.setFieldInfo(properties[i].getFieldInfo());
			vo.setName(properties[i].getName());
			vo.setType(convertTypeStr(properties[i].getType()));
			
			list.add(vo);
		}
		result.setProperties(list.toArray(new FieldVO[list.size()]));
		return result;
	}

なんてものを追加。画面用VOでは型をStringに変換しなくては・・・
的な事があって、それくらいテンプレートで・・・
と思ってたんだけど意外に面倒くさい。
というわけで簡単なレイアウト以外はここで細工しましょう的な感じになりました。
それにしてもユーティリティって扱いはどうかと思うけど・・・
まぁいいか


レイアウト以外はやはりごりごり書くか・・・
ってやってたらどんどんボリュームが増えてきた(^^;

package sample.covert;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;

public class ReflectClassObjectFactory {
	Class origClass = null;
	
	public ReflectClassObjectFactory(String className) throws Exception{
		Class.forName(className);
	}
	public ReflectClassObjectFactory(Class clazz) {
		this.origClass = clazz;
	}
	
	public ReflectClassObjectFactory(Object o) {
		origClass = o.getClass();
	}
	
	public static ClassObject createClassObject(String className) throws Exception {
		ReflectClassObjectFactory source = new ReflectClassObjectFactory(className);
		return source.createClass();
	}
	
	public static ClassObject createClassObject(Class clazz) {
		ReflectClassObjectFactory source = new ReflectClassObjectFactory(clazz);
		return source.createClass();
	}
	
	public static ClassObject createClassObject(Object o) {
		ReflectClassObjectFactory source = new ReflectClassObjectFactory(o);
		return source.createClass();
	}
	
	public ClassObject createClass() {
		ClassObject result = new ClassObject();
		result.setClassName(getClassNameByClazz());
		
		result.setPackageStr(getPackageNameByClazz());
		
		result.setProperties(getFieldVOArrayByClazz());
		return result;
	}

	private String getClassNameByClazz() {
		return origClass.getSimpleName();
	}

	
	private String getPackageNameByClazz() {
		Package packageObj = origClass.getPackage();
		return packageObj.getName();
	}
		
	private FieldVO[] getFieldVOArrayByClazz() {
		//親のものは除く
		Field[] fields = origClass.getDeclaredFields();
		ArrayList<FieldVO> list = new ArrayList<FieldVO>();
		for (int i = 0; i < fields.length; i++) {
			FieldVO vo = convertFieldForFieldVO(fields[i]);
			if(vo == null) {
				continue;
			}
			list.add(vo);
		}
		return list.toArray(new FieldVO[list.size()]);
	}
	
	/**
	 * fieldで不要なものを除く必要がある場合、ここで制限する。
	 * @param field Field
	 * @return FieldVO
	 */
	private static FieldVO convertFieldForFieldVO(Field field) {
		FieldVO vo = new FieldVO();
		
		int modifiers = field.getModifiers();
		//static はコピーしない
		//private のもののみとする。
		//nativeとかはまぁいいか
		if(Modifier.isStatic(modifiers) || !Modifier.isPrivate(modifiers)) {
			return null;
		}
		
		vo.setName(field.getName());
		
		/*
		 * nameしないとinterfaceとかつくことも
		 * ジェネリクスつけたい場合には、getGenericType()
		 * ただし、こっちを使うと、
		 * ジェネリクスがついていないばあいに、
		 * classとかが付いてくる
		 * field.getType().getName()と、field.getType().getGenericType()
		 * の一致を図ればよい? 
		 * ?field.getType(); 
		 * ?field.getType().getName();
		 * ?field.getGenericType();
		 * 
		 * ?と?が同じ場合、ジェネリクスなしで、?が型の名前 
		 * ?と?が異なる場合、ジェネリクスありで、?が型の名前
		 * 
		 * とできそうな。。。
		 */
		vo.setType(getTypeName(field));
		
		VarName annotation = field.getAnnotation(VarName.class);
		if(annotation == null || annotation.value().length() == 0) {
			vo.setFieldInfo(field.getName());
		} else {
			vo.setFieldInfo(annotation.value());
		}
		return vo;
	}
	private static String getTypeName(Field field) {
		if(field.getType().equals(field.getGenericType())) {
//			return field.getGenericType();
			return field.getType().getName();
		} else {
			return field.getType().getName();
		}
	}
}

ざっくりと、リフレクションでVOに値を設定するようなクラス。
これと、ExcelからとってきてClassObjectにするようなものを用意すれば
後はつながりそうかな。と。
それはそうと、
List list;
List list;
でFiledから取れる情報が違ってるんだけど・・・
一応上述のような判断でジェネリクス込みとかでいけるとは思うんだけど
自信はないなぁ・・・

package sample.covert;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import sample.io.IOUtil;

public class CodeGen {
	
	/*
	 * 以下を設定すること
	 */
	private String destDirStr = "C:/tmp";
	
	private File destDir = null;
	
	private String packageName = null;
	
	/**
	 * 出力ディレクトリを指定するコンストラクタ
	 * パッケージは元ファイルとルールに従う
	 * @param destDirStr 出力ディレクトリ
	 */
	public CodeGen(String destDirStr) {
		this(destDirStr, null);
	}
	
	/**
	 * 出力ディレクトリを指定するコンストラクタ
	 * パッケージは元ファイルとルールに従う
	 * @param destDir 出力ディレクトリ
	 */
	public CodeGen(File destDir) {
		this(destDir, null);
	}
	
	
	/**
	 * 出力ディレクトリを指定するコンストラクタ
	 * パッケージは指定されたパッケージとする。
	 * nullの場合は未指定と同じ扱いとする。
	 * @param destDirStr 出力ディレクトリ
	 */
	public CodeGen(String destDirStr, String packageName) {
		this(new File(destDirStr), packageName);
	}
	
	/**
	 * 出力ディレクトリを指定するコンストラクタ
	 * パッケージは指定されたパッケージとする。
	 * nullの場合は未指定と同じ扱いとする。
	 * @param destDir 出力ディレクトリ
	 */
	public CodeGen(File destDir, String packageName) {
		if(destDir == null || !destDir.isDirectory()) {
			throw new IllegalArgumentException("出力ディレクトリは正しく指定してください");
		}
		this.destDir = destDir;
		this.packageName = packageName;
	}
	
	/**
	 * 指定されたクラスを元として出力処理を行う。
	 * @param clazz
	 */
	public void execute(Class clazz) {
		ClassObject object = ReflectClassObjectFactory.createClassObject(clazz);
		execute(object);
	}
	
	/**
	 * 指定されたオブジェクトを元として出力処理を行う
	 * @param o 
	 */
	public void execute(Object o) {
		ClassObject object = ReflectClassObjectFactory.createClassObject(o);
		execute(object);
	}
	
	/**
	 * 指定されたクラス名を元として出力処理を行う。
	 * @param className
	 * @throws Exception クラス名が存在しない
	 */
	public void execute(String className) throws Exception {
		
		ClassObject object = ReflectClassObjectFactory.createClassObject(className);
		execute(object);
	}
	
	/**
	 * 指定されたClassObjectを元として出力処理を行う。
	 * @param source
	 */
	public void execute(final ClassObject source) {
		
		ClassObject formBean = ConvertUtil.convertForFormVO(source);
		
		executeVelocity(formBean);
	}
	
	protected void executeVelocity(ClassObject source) {
		Writer writer = null;
		source.setPackageStr(packageName);
		try {
			writer = createWriter(source);
			
			Velocity.init("velocity.properties");
			VelocityContext vc = new VelocityContext();
			vc.put("source", source);
			
			Template template = Velocity.getTemplate("formvo.vm");

			template.merge(vc, writer);

			writer.flush();
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtil.close(writer);
		}
	}
	
	protected Writer createWriter(ClassObject source) throws IOException {
		String className = source.getFullClassName();
		File file = createFile(destDir, className);
		FileWriter fw = new FileWriter(file);
		return fw;
	}
	
	/**
	 * 指定ディレクトリに、パッケージの階層を作成して返す。
	 * @param parent 親ディレクトリ
	 * @param className クラスの完全修飾名
	 * @return 作成クラスfile
	 * @throws IOException 
	 */
	protected File createFile(File parent, String className) throws IOException {
		String path = className.replaceAll("\\.", "/");
		File child = new File(parent, path + ".java");

		child.getParentFile().mkdirs();
		child.createNewFile();
		return child;
	}
}

こんなんで部品は大体そろったかな?
前のはほとんど変わってるかもしれないけど。。。というか変わってるけど。

あとはもう少し変換の不要な、もとVOの作成はちゃちゃっと追加できるとして・・・

残りの
コンバートメソッドの作成(画面側VOに)
ってのと、TestCaseの自動生成か・・・
って感じですね

雑感

しかし・・・Factoryじゃないよなぁ・・・