[Jiemamy-notify] commit [2170] [CORE-80] ChangeSupportの自動修正もバブリング対応した。

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2008年 11月 19日 (水) 01:51:41 JST


Revision: 2170
          http://svn.sourceforge.jp/view?root=jiemamy&view=rev&rev=2170
Author:   shin1
Date:     2008-11-19 01:51:41 +0900 (Wed, 19 Nov 2008)

Log Message:
-----------
[CORE-80]ChangeSupportの自動修正もバブリング対応した。

Modified Paths:
--------------
    sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/java/org/jiemamy/core/eventcodegen/CollectionProperty.java
    sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/java/org/jiemamy/core/eventcodegen/JiemamyModelDoclet.java
    sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/resources/ChangeSupportImpl.vm


-------------- next part --------------
Modified: sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/java/org/jiemamy/core/eventcodegen/CollectionProperty.java
===================================================================
--- sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/java/org/jiemamy/core/eventcodegen/CollectionProperty.java	2008-11-18 16:40:43 UTC (rev 2169)
+++ sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/java/org/jiemamy/core/eventcodegen/CollectionProperty.java	2008-11-18 16:51:41 UTC (rev 2170)
@@ -9,6 +9,7 @@
 import org.jiemamy.event.collectionimpl.ObservableSet;
 
 public class CollectionProperty {
+	private String getterName;
 	private String name;
 	private String nameUpper;
 	private String nameSingle;
@@ -181,4 +182,12 @@
 	public void setMap(boolean isMap) {
 		this.isMap = isMap;
 	}
+
+	public String getGetterName() {
+		return getterName;
+	}
+
+	public void setGetterName(String getterName) {
+		this.getterName = getterName;
+	}
 }

Modified: sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/java/org/jiemamy/core/eventcodegen/JiemamyModelDoclet.java
===================================================================
--- sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/java/org/jiemamy/core/eventcodegen/JiemamyModelDoclet.java	2008-11-18 16:40:43 UTC (rev 2169)
+++ sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/java/org/jiemamy/core/eventcodegen/JiemamyModelDoclet.java	2008-11-18 16:51:41 UTC (rev 2170)
@@ -2,7 +2,6 @@
 
 import java.io.File;
 import java.io.FileWriter;
-import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -16,16 +15,17 @@
 import org.apache.velocity.app.Velocity;
 import org.apache.velocity.exception.ParseErrorException;
 import org.apache.velocity.exception.ResourceNotFoundException;
+import org.jiemamy.core.model.AbstractModel;
 import org.jiemamy.spec.model.JiemamyModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import com.sun.javadoc.AnnotationDesc;
 import com.sun.javadoc.ClassDoc;
 import com.sun.javadoc.Doclet;
 import com.sun.javadoc.FieldDoc;
 import com.sun.javadoc.LanguageVersion;
 import com.sun.javadoc.RootDoc;
 import com.sun.javadoc.Type;
-import com.sun.javadoc.AnnotationDesc.ElementValuePair;
 
 /**
  * Event用のソースを自動生成する。 j-coreプロジェクト配下のソースを読み込み、 {@link JiemamyModel}を発見した場合にその{@link JiemamyModel}用のChangeListenerとChangeSupportを自動生成する。
@@ -43,9 +43,9 @@
  * Imports」と「Source-Format」を行ってからCommitする事。
  * <ul>
  * <li>../org.jiemamy.event/src/main/java/org/event/model配下の全てのフォルダ</li>
- * <li>../org.jiemamy.spec.event/src/main/java/org/event/model配下の全てのフォルダ</li>
  * </ul>
  * </li>
+ * <li>また、RootModelだけgetterの名称にModifiableを付加する必要がある。</li>
  * </ul>
  * 
  * @author shin1ogawa
@@ -54,7 +54,7 @@
 	public List<JiemamyModel> model;
 	public Map<Class<?>, CollectionProperty> collectionProperties = new HashMap<Class<?>, CollectionProperty>();
 	public static final String OUTPUTDIR_IMPLEMENTS = "../org.jiemamy.event/src/main/java/";
-	public static final String OUTPUTDIR_SPECS = "../org.jiemamy.spec.event/src/main/java/";
+	static Logger logger = LoggerFactory.getLogger(JiemamyModelDoclet.class);
 
 	public static LanguageVersion languageVersion() {
 		return LanguageVersion.JAVA_1_5;
@@ -98,19 +98,24 @@
 	 * 読み込んだ{@link ClassDoc}を処理する。
 	 * 
 	 * @param classDoc
+	 * @throws Exception
+	 * @throws ParseErrorException
+	 * @throws ResourceNotFoundException
 	 */
-	public static void processClassDoc(ClassDoc classDoc) {
-		try {
+	public static void processClassDoc(ClassDoc classDoc)
+			throws ResourceNotFoundException, ParseErrorException, Exception {
+
+		if (!classDoc.isAbstract() && !classDoc.isEnum()
+				&& !classDoc.simpleTypeName().startsWith("Abstract")
+				&& !classDoc.simpleTypeName().endsWith("Adapter")) {
 			try {
-				Class<?> clazz = Class.forName(classDoc.qualifiedName());
-				// JiemamyModelのサブクラスでないものはClassCastExceptionを発生させて弾く。
-				clazz.asSubclass(JiemamyModel.class);
-				processModel(classDoc);
+				Class<?> clazz = Class.forName(classDoc.qualifiedTypeName());
+				if (AbstractModel.class.isAssignableFrom(clazz)) {
+					processModelAccessor(classDoc);
+				}
 			} catch (Exception ex) {
-				// 無視する。
+				return;
 			}
-		} catch (Exception ex) {
-			//
 		}
 	}
 
@@ -126,178 +131,116 @@
 	 * @throws ParseErrorException
 	 * @throws ResourceNotFoundException
 	 */
-	private static void processModel(ClassDoc classDoc)
+	private static void processModelAccessor(ClassDoc classDoc)
 			throws ResourceNotFoundException, ParseErrorException, Exception {
-		System.out.println(classDoc.qualifiedTypeName() + ":"
-				+ getPackageName(classDoc));
+		// Importが必要なClass
 		List<String> importClasses = new ArrayList<String>();
-		addImportClasses(importClasses, classDoc.qualifiedTypeName());
-		addImportClasses(importClasses,
-				"org.jiemamy.spec.event.ModelChangeListener");
-		addImportClasses(importClasses,
-				"org.jiemamy.spec.event.ObservableCollectionChangeEvent");
+		importClasses.add("org.jiemamy.event.AbstractModelChangeSupport");
+		importClasses.add("org.jiemamy.spec.event.ModelChangeEvent");
+		importClasses.add("org.jiemamy.spec.event.ModelChangeListener");
+		importClasses.add("org.jiemamy.spec.event.ModelChangeSupport");
+		importClasses.add("org.jiemamy.spec.event.Observable");
+		// 属性の情報を保持するCollectionPropertyのList
 		List<CollectionProperty> properties = new ArrayList<CollectionProperty>();
-		FieldDoc[] fields = classDoc.fields();
-		for (FieldDoc fieldDoc : fields) {
-			// Bindingアノテーションで修飾されているかを調査する。
-			boolean hasBindingAnnotation = false;
-			AnnotationDesc[] annotations = fieldDoc.annotations();
-			for (AnnotationDesc annotation : annotations) {
-				String annotationType = annotation.annotationType()
-						.qualifiedName();
-				if (annotationType
-						.equals("org.seasar.framework.container.annotation.tiger.Binding")) {
-					ElementValuePair[] elementValues = annotation
-							.elementValues();
-					for (ElementValuePair elementValue : elementValues) {
-						String valueString = elementValue.value().toString()
-								.replaceAll("\"", "");
-						String elementString = elementValue.element()
-								.toString();
-						if (elementString
-								.equals("org.seasar.framework.container.annotation.tiger.Binding.value()")
-								&& (valueString.equals("set")
-										|| valueString.equals("list") || valueString
-										.equals("map"))) {
-							// Bindingアノテーションのその引数が"list" "map"
-							// "set"のいずれかであるものが対象。
-							hasBindingAnnotation = true;
-							break;
-						}
-					}
-				}
-			}
-			if (hasBindingAnnotation == false) {
+		for (FieldDoc fieldDoc : classDoc.fields()) {
+			Type returnType = fieldDoc.type();
+			String returnTypeName = returnType.qualifiedTypeName();
+			String fieldName = fieldDoc.name();
+			String getterName = fieldDoc.name();
+			getterName = "get" + getterName.substring(0, 1).toUpperCase()
+					+ getterName.substring(1);
+			// インスタンス化してみる。
+			Class<?> fieldType;
+			try {
+				fieldType = Class.forName(returnTypeName);
+			} catch (Exception ex) {
+				// インスタンス化できない。
 				continue;
 			}
-
-			Type type = fieldDoc.type();
-			String fieldTypeName = type.qualifiedTypeName();
-			Class<?> fieldType = Class.forName(fieldTypeName);
-			if (isSubClass(fieldType, List.class)
-					|| isSubClass(fieldType, List.class)) {
+			if (List.class.isAssignableFrom(fieldType)
+					|| Set.class.isAssignableFrom(fieldType)) {
 				// ListまたはSetのサブクラス
-				String parameterClassName = getParameterClassName(fieldDoc);
-				addImportClasses(importClasses, fieldTypeName);
+				String parameterClassName = getParameterClassName(returnType);
+				addImportClasses(importClasses, returnTypeName);
 				addImportClasses(importClasses, parameterClassName);
-				properties.add(new CollectionProperty(fieldDoc.name(), type
-						.qualifiedTypeName().toString(), parameterClassName));
-			} else if (isSubClass(fieldType, Map.class)) {
+				CollectionProperty collectionProperty = new CollectionProperty(
+						fieldName, returnType.qualifiedTypeName().toString(),
+						parameterClassName);
+				properties.add(collectionProperty);
+				collectionProperty.setGetterName(getterName);
+			} else if (Map.class.isAssignableFrom(fieldType)) {
 				// Mapのサブクラス
-				String[] parameterClassNames = getParameterClassNames(fieldDoc);
-				addImportClasses(importClasses, fieldTypeName);
+				String[] parameterClassNames = getParameterClassNames(returnType);
+				addImportClasses(importClasses, returnTypeName);
 				addImportClasses(importClasses, parameterClassNames[0]);
 				addImportClasses(importClasses, parameterClassNames[1]);
-				try {
-					CollectionProperty collectionProperty = new CollectionProperty(
-							fieldDoc.name(), type.qualifiedTypeName()
-									.toString(), parameterClassNames[1]);
-					collectionProperty
-							.setMapKeyClassName(parameterClassNames[0]);
-					properties.add(collectionProperty);
-				} catch (Exception ex) {
-					ex.printStackTrace();
-				}
+				CollectionProperty collectionProperty = new CollectionProperty(
+						fieldName, returnType.qualifiedTypeName().toString(),
+						parameterClassNames[1]);
+				collectionProperty.setMapKeyClassName(parameterClassNames[0]);
+				properties.add(collectionProperty);
+				collectionProperty.setGetterName(getterName);
 			}
 		}
 		Collections.sort(importClasses);
 		// Templateからjavaファイルを生成する。
 		try {
 			String packageName = getPackageName(classDoc).replaceAll(
-					"org.jiemamy.core", "org.jiemamy.spec.event");
-			File dirForSpec = new File(OUTPUTDIR_SPECS
+					"org.jiemamy.core.model", "org.jiemamy.event.model");
+			File dir = new File(OUTPUTDIR_IMPLEMENTS
 					+ packageName.replaceAll("\\.", "/"));
-			if (!dirForSpec.exists()) {
-				dirForSpec.mkdirs();
+			if (!dir.exists()) {
+				dir.mkdirs();
 			}
-			// 実装のパッケージ名には"spec"を含まない。
-			File dirForImpl = new File(OUTPUTDIR_IMPLEMENTS
-					+ packageName.replaceAll("\\.spec", "").replaceAll("\\.",
-							"/"));
-			if (!dirForImpl.exists()) {
-				dirForImpl.mkdirs();
-			}
-			VelocityContext velocityContext = new VelocityContext();
-			velocityContext.put("package", packageName);
-			velocityContext.put("importClasses", importClasses);
+
 			String modelClassName = classDoc.name().toString().replace("Impl",
 					"");
-			velocityContext.put("modelClassName", modelClassName);
-			velocityContext.put("modelClassNameLower", classDoc.name()
-					.toString().substring(0, 1).toLowerCase()
-					+ classDoc.name().toString().substring(1));
-			velocityContext.put("properties", properties);
-
-			// ChangeListenerの生成
-			Template listenerTemplate = Velocity
-					.getTemplate("ChangeListener.vm");
-			File file = new File(dirForSpec.getAbsolutePath() + "/"
-					+ modelClassName + "ChangeListener.java");
-			System.out.println(file.getAbsolutePath());
-			Writer writer = new FileWriter(file);
-			listenerTemplate.merge(velocityContext, writer);
-			writer.flush();
-			writer.close();
-
-			// ChangeSupportの生成
-			addImportClasses(importClasses, "java.util.List");
-			addImportClasses(importClasses, "java.util.ArrayList");
-			addImportClasses(importClasses,
-					"org.jiemamy.spec.event.ModelChangeEvent");
+			importClasses.add(getPackageName(classDoc).replaceAll(
+					"org.jiemamy.core.model", "org.jiemamy.spec.model")
+					+ "." + modelClassName); // Model Interface
 			if (properties.size() > 0) {
+				importClasses.add("java.lang.ref.WeakReference");
+				importClasses.add("org.slf4j.Logger");
+				importClasses.add("org.slf4j.LoggerFactory");
 				importClasses
 						.add("org.jiemamy.spec.event.ObservableCollectionChangeListener");
+				importClasses.add("org.seasar.framework.beans.BeanDesc");
+				importClasses
+						.add("org.seasar.framework.beans.impl.BeanDescImpl");
+				importClasses
+						.add("org.jiemamy.spec.event.ObservableCollectionChangeEvent");
+				importClasses
+						.add("org.jiemamy.spec.event.ObservableCollectionChangeEvent.Timing");
+				importClasses.add(classDoc.qualifiedName()); // Model
+				// Implementation
+				importClasses.add(getPackageName(classDoc).replaceAll(
+						"org.jiemamy.core.model", "org.jiemamy.spec.accessor")
+						+ "." + modelClassName + "Accessor"); // Model
+				// Implementation
 			}
 			for (CollectionProperty property : properties) {
 				addImportClasses(importClasses, property
 						.getObservableCollectionClassName());
 			}
-			Collections.sort(importClasses);
-			Template supportTemplate = Velocity.getTemplate("ChangeSupport.vm");
-			file = new File(dirForSpec.getAbsolutePath() + "/" + modelClassName
-					+ "ChangeSupport.java");
-			System.out.println(file.getAbsolutePath());
-			writer = new FileWriter(file);
-			supportTemplate.merge(velocityContext, writer);
-			writer.flush();
-			writer.close();
 
+			VelocityContext velocityContext = new VelocityContext();
+			velocityContext.put("package", packageName);
+			velocityContext.put("importClasses", importClasses);
+			velocityContext.put("modelClassName", modelClassName);
+			velocityContext.put("modelClassNameLower", classDoc.name()
+					.toString().substring(0, 1).toLowerCase()
+					+ classDoc.name().toString().substring(1));
+			velocityContext.put("properties", properties);
 			// ChangeSupportImplの生成
 			velocityContext.put("package", packageName
 					.replaceAll("\\.spec", ""));
-			addImportClasses(importClasses, "java.util.List");
-			addImportClasses(importClasses, "java.util.ArrayList");
-			addImportClasses(importClasses, "org.jiemamy.spec.event.Observable");
-			addImportClasses(importClasses, packageName.replace(".event", "")
-					+ "." + modelClassName.replace("Impl", ""));
-			addImportClasses(importClasses,
-					"org.jiemamy.spec.event.ModelChangeEvent");
-			addImportClasses(importClasses,
-					"org.jiemamy.event.AbstractModelChangeSupport");
-			addImportClasses(importClasses,
-					"org.jiemamy.spec.event.ModelChangeSupport");
-			addImportClasses(importClasses,
-					"org.seasar.framework.beans.BeanDesc");
-			addImportClasses(importClasses,
-					"org.seasar.framework.beans.impl.BeanDescImpl");
-			addImportClasses(importClasses,
-					"org.jiemamy.spec.event.ObservableCollectionChangeEvent.Timing");
-			if (properties.size() > 0) {
-				importClasses
-						.add("org.jiemamy.spec.event.ObservableCollectionChangeListener");
-			}
-			for (CollectionProperty property : properties) {
-				addImportClasses(importClasses, property
-						.getObservableCollectionClassName());
-			}
 			Collections.sort(importClasses);
-			Template supportImplTemplate = Velocity
-					.getTemplate("ChangeSupportImpl.vm");
-			file = new File(dirForImpl.getAbsolutePath() + "/" + modelClassName
+			Template template = Velocity.getTemplate("ChangeSupportImpl.vm");
+			File file = new File(dir.getAbsolutePath() + "/" + modelClassName
 					+ "ChangeSupportImpl.java");
-			System.out.println(file.getAbsolutePath());
-			writer = new FileWriter(file);
-			supportImplTemplate.merge(velocityContext, writer);
+			logger.info(file.getAbsolutePath());
+			FileWriter writer = new FileWriter(file);
+			template.merge(velocityContext, writer);
 			writer.flush();
 			writer.close();
 		} catch (Exception ex) {
@@ -305,21 +248,23 @@
 		}
 	}
 
-	/**
-	 * あるクラスがあるクラスのサブクラスかどうか。
-	 * 
-	 * @param subClass
-	 * @param superClass
-	 * @return
-	 */
-	private static boolean isSubClass(Class<?> subClass, Class<?> superClass) {
-		try {
-			subClass.asSubclass(superClass);
-			return true;
-		} catch (Exception ex) {
-			return false;
-		}
-	}
+	//
+	// /**
+	// * あるクラスがあるクラスのサブクラスかどうか。
+	// *
+	// * @param subClass
+	// * @param superClass
+	// * @return
+	// */
+	// private static boolean isSubClass(Class<?> subClass, Class<?> superClass)
+	// {
+	// try {
+	// subClass.asSubclass(superClass);
+	// return true;
+	// } catch (Exception ex) {
+	// return false;
+	// }
+	// }
 
 	/**
 	 * パッケージ名を取得する。
@@ -338,9 +283,8 @@
 	 * @param fieldDoc
 	 * @return
 	 */
-	private static String getParameterClassName(FieldDoc fieldDoc) {
-		String parameterizedType = fieldDoc.type().asParameterizedType()
-				.toString();
+	private static String getParameterClassName(Type type) {
+		String parameterizedType = type.asParameterizedType().toString();
 		int index1 = parameterizedType.indexOf('<');
 		int index2 = parameterizedType.lastIndexOf('>');
 		return parameterizedType.substring(index1 + 1, index2);
@@ -352,9 +296,8 @@
 	 * @param fieldDoc
 	 * @return
 	 */
-	private static String[] getParameterClassNames(FieldDoc fieldDoc) {
-		String parameterizedType = fieldDoc.type().asParameterizedType()
-				.toString();
+	private static String[] getParameterClassNames(Type type) {
+		String parameterizedType = type.asParameterizedType().toString();
 		int index1 = parameterizedType.indexOf('<');
 		int index2 = parameterizedType.lastIndexOf('>');
 		return parameterizedType.substring(index1 + 1, index2).split(",");

Modified: sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/resources/ChangeSupportImpl.vm
===================================================================
--- sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/resources/ChangeSupportImpl.vm	2008-11-18 16:40:43 UTC (rev 2169)
+++ sandbox/org.jiemamy.core.eventcodegen/trunk/org.jiemamy.core.eventcodegen/src/main/resources/ChangeSupportImpl.vm	2008-11-18 16:51:41 UTC (rev 2170)
@@ -28,12 +28,13 @@
  * @author shin1ogawa
  */
 public class ${modelClassName}ChangeSupportImpl extends AbstractModelChangeSupport implements ModelChangeSupport {
-	
+#if(${properties.size()} > 0)
 	private static Logger logger = LoggerFactory.getLogger(ModelChangeSupport.class);
 	
 	/** イベント発火元となるModel */
 	private WeakReference<${modelClassName}> eventTarget;
 	
+#end
 #foreach($property in $properties)
 	
 	/** 
@@ -49,9 +50,9 @@
 				 * {@inheritDoc}
 				 */
 				public void collectionChanged(ObservableCollectionChangeEvent<${property.collectionClassSimpleName}<#if(${property.map} != false)${property.mapKeyClassSimpleName}, #end${property.elementClassSimpleName}>, ${property.elementClassSimpleName}> event) {
-					if (event.getTiming() != ObservableCollectionChangeEvent.Timing.BEFORE_ADD
-							&& event.getTiming() != ObservableCollectionChangeEvent.Timing.BEFORE_REMOVE
-							&& event.getTiming() != ObservableCollectionChangeEvent.Timing.BEFORE_SET) {
+					if (event.getTiming() != Timing.BEFORE_ADD
+							&& event.getTiming() != Timing.BEFORE_REMOVE
+							&& event.getTiming() != Timing.BEFORE_SET) {
 						if (event.getTiming() == Timing.COLLECTION_CHANGED) {
 							event.setSource(event.getModel());
 						} else {
@@ -86,11 +87,13 @@
 	 * @category instance creation
 	 */
 	public ${modelClassName}ChangeSupportImpl(${modelClassName} source) {
+#if(${properties.size()} > 0)
 		${modelClassName}Accessor accessor = (${modelClassName}Accessor) source;
+		eventTarget = new WeakReference<${modelClassName}>(source);
+#end
 		source.getAdapter(Observable.class).addModelChangeListener(modelChangeListener);
-		eventTarget = new WeakReference<${modelClassName}>(source);
 #foreach($property in $properties)
-		((${property.observableCollectionClassSimpleName}<#if(${property.map} != false)${property.mapKeyClassSimpleName}, #end${property.elementClassSimpleName}>) accessor.get${property.nameUpper}()).addListener(${property.name}CollectionChangeListener);
+		((${property.observableCollectionClassSimpleName}<#if(${property.map} != false)${property.mapKeyClassSimpleName}, #end${property.elementClassSimpleName}>) accessor.${property.getterName}()).addListener(${property.name}CollectionChangeListener);
 #end
 	}
 	


Jiemamy-notify メーリングリストの案内
Back to archive index