You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by pp...@apache.org on 2007/07/23 05:57:12 UTC

svn commit: r558596 - in /labs/fluid: ./ src/main/java/org/apache/openjpa/code/ src/main/java/org/apache/openjpa/sdo/ src/main/resources/org/apache/openjpa/sdo/ src/site/ src/site/resources/ src/site/resources/images/ src/test/java/example/ src/test/ja...

Author: ppoddar
Date: Sun Jul 22 20:57:08 2007
New Revision: 558596

URL: http://svn.apache.org/viewvc?view=rev&rev=558596
Log:
Source Code based SDO support first working draft

Added:
    labs/fluid/src/site/
    labs/fluid/src/site/resources/
    labs/fluid/src/site/resources/images/
    labs/fluid/src/site/site.xml
    labs/fluid/src/test/java/example/
    labs/fluid/src/test/java/example/basic/
    labs/fluid/src/test/java/example/basic/TestCRUD.java
    labs/fluid/src/test/java/test/TestSourceCode.java
    labs/fluid/src/test/java/test/common/
    labs/fluid/src/test/java/test/common/AbstractSDOTest.java
      - copied, changed from r558139, labs/fluid/src/test/java/test/AbstractSDOTest.java
Removed:
    labs/fluid/src/test/java/test/AbstractSDOTest.java
Modified:
    labs/fluid/pom.xml
    labs/fluid/src/main/java/org/apache/openjpa/code/SDO2POJOGenerator.java
    labs/fluid/src/main/java/org/apache/openjpa/code/SourceCode.java
    labs/fluid/src/main/java/org/apache/openjpa/sdo/ImplHelper.java
    labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManager.java
    labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManagerFactory.java
    labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOMetaDataFactory.java
    labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOTypeRepository.java
    labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties
    labs/fluid/src/test/java/test/TestModel.java
    labs/fluid/src/test/java/test/TestSDO.java
    labs/fluid/src/test/resources/META-INF/persistence.xml

Modified: labs/fluid/pom.xml
URL: http://svn.apache.org/viewvc/labs/fluid/pom.xml?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/pom.xml (original)
+++ labs/fluid/pom.xml Sun Jul 22 20:57:08 2007
@@ -1,5 +1,8 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+<project 
+  xmlns="http://maven.apache.org/POM/4.0.0" 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.openjpa</groupId>
   <artifactId>sdo-persistence</artifactId>
@@ -7,6 +10,7 @@
   <version>0.1.0-SNAPSHOT</version>
   <name>SDO Persistence</name>
   <url>http://openjpa.apache.org</url>
+  
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -14,18 +18,20 @@
       <version>3.8.1</version>
       <scope>test</scope>
     </dependency>
-        <dependency>
-            <groupId>org.apache.openjpa</groupId>
-            <artifactId>openjpa</artifactId>
-            <version>1.0.0-SNAPSHOT</version>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.openjpa</groupId>
-            <artifactId>openjpa-lib</artifactId>
-            <version>1.0.0-SNAPSHOT</version>
-            <scope>compile</scope>
-        </dependency>
+    
+    <dependency>
+      <groupId>org.apache.openjpa</groupId>
+      <artifactId>openjpa</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    
+    <dependency>
+       <groupId>org.apache.openjpa</groupId>
+       <artifactId>openjpa-lib</artifactId>
+       <version>1.0.0-SNAPSHOT</version>
+       <scope>compile</scope>
+    </dependency>
     
     <dependency>
       <groupId>net.sourceforge.serp</groupId>
@@ -33,32 +39,27 @@
   	  <version>1.13.0</version>
   	  <scope>compile</scope>
     </dependency>
-        <dependency>
+        
+    <dependency>
       <groupId>org.apache.tuscany.sdo</groupId>
   	  <artifactId>tuscany-sdo-impl</artifactId>
   	  <version>1.0-incubating-beta1</version>
   	  <scope>compile</scope>
     </dependency>
-                <dependency>
-                    <groupId>mysql</groupId>
-                    <artifactId>mysql-connector-java</artifactId>
-                    <version>5.0.4</version>
-                    <scope>test</scope>
-                </dependency>
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-            <version>3.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-            <version>3.2</version>
-            <scope>test</scope>
-        </dependency>
-        
     
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>5.0.4</version>
+      <scope>test</scope>
+    </dependency>
+    
+    <dependency>
+      <groupId>commons-collections</groupId>
+      <artifactId>commons-collections</artifactId>
+      <version>3.2</version>
+      <scope>test</scope>
+    </dependency>       
   </dependencies>
   
     <build>
@@ -70,17 +71,19 @@
                     <target>1.5</target>
                 </configuration>
             </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <forkMode>pertest</forkMode>
-          <disableXmlReport>true</disableXmlReport>
-          <trimStackTrace>true</trimStackTrace>
-        </configuration>
-      </plugin>
+            <plugin>
+        		<groupId>org.apache.maven.plugins</groupId>
+        		<artifactId>maven-surefire-plugin</artifactId>
+        		<configuration>
+          			<forkMode>pertest</forkMode>
+          			<disableXmlReport>true</disableXmlReport>
+          			<trimStackTrace>true</trimStackTrace>
+        		</configuration>
+      		</plugin>
         </plugins>
     </build>  
+    
+    
     <profiles>    
         <profile>
             <!--                        

Modified: labs/fluid/src/main/java/org/apache/openjpa/code/SDO2POJOGenerator.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/main/java/org/apache/openjpa/code/SDO2POJOGenerator.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/main/java/org/apache/openjpa/code/SDO2POJOGenerator.java (original)
+++ labs/fluid/src/main/java/org/apache/openjpa/code/SDO2POJOGenerator.java Sun Jul 22 20:57:08 2007
@@ -27,6 +27,8 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.persistence.PersistenceUnit;
+
 import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.lib.log.LogFactory;
 import org.apache.openjpa.lib.log.LogFactoryImpl;
@@ -35,6 +37,7 @@
 import org.apache.openjpa.lib.util.Options;
 import org.apache.openjpa.sdo.ImplHelper;
 import org.apache.openjpa.util.UserException;
+import org.w3c.dom.Document;
 
 import commonj.sdo.Property;
 import commonj.sdo.Type;
@@ -54,41 +57,71 @@
 	private Map<Type, SourceCode> _cache = new HashMap<Type, SourceCode>();
 	private LogFactoryImpl logFactory;
 	private Log _log;
-	private File  _root = new File(System.getProperty("user.dir"));
+	
+	private File _root;
 	private String rootDirectory;
+	private Flags flags;
+	private XMLReadWrite pUnit;
 
 	SDO2POJOGenerator() {
+		this(null);
+	}
+	
+	SDO2POJOGenerator(Flags flags) {
+		this.flags = (flags==null) ? new Flags() : flags;
 		logFactory = new LogFactoryImpl();
-		logFactory.setDefaultLevel(LogFactoryImpl.WARN_STR);
+		logFactory.setDefaultLevel(LogFactoryImpl.getLevel(flags.logLevel));
 		_log = logFactory.getLog("SDO2Java");
+
+		if (flags.mergeUnit) {
+			InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/persistence.xml");
+			if (is != null) {
+				try {
+					pUnit = new XMLReadWrite(is);
+				} catch (Exception e) {
+					pUnit = null;
+					this.flags.mergeUnit = false;
+				}
+			} else {
+				_log.warn(_loc.get("punit-not-found"));
+			}
+		}
+		setRootDirectory(flags.rootDir);
 	}
 
+
 	/**
-	 * Get a Java class corresponding to a SDO Type. Dynamically generate the
-	 * Java class if it does not exist and <code>mustExist</code> is true.
-	 * <br>
+	 * Get a Java class corresponding to a SDO Type. 
 	 */
 	public SourceCode getJavaClass(Type type) {
-		SourceCode cls = _cache.get(type);
-		if (cls != null)
-			return cls;
+		if (type == null)
+			throw new NullPointerException("null-type");
+		if (type.isDataType())
+			throw new IllegalArgumentException(
+				_loc.get("data-type-not-converted", type.getName()).toString());
+		if (type.isSequenced())
+			throw new IllegalArgumentException(
+				_loc.get("data-type-not-converted", type.getName()).toString());
+		if (ImplHelper.isContainer(type))
+			throw new IllegalArgumentException(
+					_loc.get("container-type-not-converted", type.getName()).toString());
 		
+		SourceCode cls = _cache.get(type);
 		if (cls == null) {
 			cls = generatePOJO(type);
 		}
 		return cls;
 	}
-
 	
-	public File getRootDirectory() {
-		return _root;
+	public String getRootDirectory() {
+		return rootDirectory;
 	}
 	
 	public String[] parseTypeNames(String resource) {
 		List<Type> types = findTypes(resource);
 		List<String> result = new ArrayList<String>();
 		for (Type type : types) {
-			result.add(ImplHelper.getClassName(type));
+			result.add(ImplHelper.getFullClassName(type));
 		}
 		return result.toArray(new String[result.size()]);
 	}
@@ -115,13 +148,11 @@
 
 		try {
 			for (Object t : types) {
-				if (t instanceof Type == false)
-					continue;
-				Type type = (Type) t;
-				if (type.isDataType() || "DocumentRoot".equals(type.getName()))
-					continue;
-
-				result.add(type);
+				if (t instanceof Type) {
+					Type type = (Type) t;
+					if (!(type.isDataType() || "DocumentRoot".equals(type.getName())))
+						result.add(type);
+				}
 			}
 		} finally  {
 			try {
@@ -132,53 +163,89 @@
 		return result;
 	}
 
+	/**
+	 * Generate the closure of POJO.
+	 * 
+	 * @param type
+	 * @return
+	 */
 	SourceCode generatePOJO(Type type) {
-		String javaClassName = ImplHelper.getClassName(type);
+		String pkgName = ImplHelper.getPackageName(type);
+		String fullClassName = ImplHelper.getFullClassName(type);
+		String javaClassName = type.getName();
 		if (_log.isInfoEnabled())
-			_log.info(_loc.get("generate-dynamic-class", javaClassName));
-		SourceCode bcls = new SourceCode(javaClassName);
-		_cache.put(type, bcls);
+			_log.info(_loc.get("generate-dynamic-class", fullClassName));
+		SourceCode code = new SourceCode(pkgName, javaClassName);
+		_cache.put(type, code);
 		
+		SourceCode.Class cls = code.getTopLevelClass();
+		if (type.isAbstract()) 
+			cls.addQualifier("abstract");
+		cls.makePublic();
+			
 		
 		// annotate the class as @Entity
-		bcls.getRoot().addAnnotation("@Entity").put("name", type.getName());
-				
+		if (flags.annotate) {
+			code.addImport("javax.persistence.*");
+			cls.addAnnotation("@Entity");
+		}
+		if (flags.mergeUnit) {
+			pUnit.insertClass(fullClassName);
+		}
 		// add private field with bean-style get/set methods for each property
 		List properties = type.getProperties();
 		for (Object p : properties) {
 			Property property = (Property) p;
 			Type propertyType = property.getType();
 			String propertyName = property.getName();
-			SourceCode propertyClass = null;
+			String javaTypeName = null;
+			SourceCode javaClass = null;
+			SourceCode.Field javaField = null;
 			if (propertyType.isDataType()) {
-				bcls.addField(propertyName, propertyType
-						.getInstanceClass().getName());
+				javaTypeName = propertyType.getInstanceClass().getName();
+				code.addImport(javaTypeName);
+				if (property.isMany())
+					javaTypeName = "List<" + javaTypeName + ">";
+				javaField = code.addField(propertyName, javaTypeName);
+			} else if (ImplHelper.isContainer(propertyType)) {
+				Type componentType = ImplHelper.getComponentType(propertyType);
+				javaClass = getJavaClass(componentType);
+				code.addImport("java.util.List");
+				javaTypeName = "List<"+componentType.getName()+">";
+				javaField = code.addField(propertyName, javaTypeName);
+				javaField.addAnnotation("@OneToMany");
+			} else if (property.isMany()) {
+				Type componentType = property.getType();
+				javaClass = getJavaClass(componentType);
+				code.addImport("java.util.List");
+				javaTypeName = "List<"+componentType.getName()+">";
+				javaField = code.addField(propertyName, javaTypeName);
+				javaField.addAnnotation("@OneToMany");
 			} else {
-				propertyClass = getJavaClass(propertyType);
-				if (property.isMany()) {
-					bcls.addField(propertyName + "List", "java.util.List");
-				} else {
-					bcls.addField(propertyName, propertyClass.getClassName());
-				}
+				javaClass = getJavaClass(propertyType);
+				javaField = code.addField(propertyName, javaClass.getClassName());
+				javaField.addAnnotation("@OneToOne");
 			}
+			javaField.addGetter();
+			if (!property.isReadOnly())
+				javaField.addSetter();
 		}
-		bcls.markAsBean();
-		bcls.getRoot().makePublic();
-		write(bcls);
-		return bcls;
+		write(code);
+		return code;
 	}
 	
 
 	File getClassFile(SourceCode bcls) {
-		File pkgdir = Files.getPackageFile(getRootDirectory(), 
-				bcls.getPackageName(), true);
+		File pkgdir = Files.getPackageFile(_root, bcls.getPackageName(), true);
 		return new File(pkgdir, bcls.getClassName() + ".java");
 	}
 
 	public void setRootDirectory(String rootDirPath) {
+		File currentDir = new File(System.getProperty("user.dir"));
+		rootDirectory = rootDirPath;
 		if (rootDirPath != null) {
 			File file = new File(rootDirPath);
-			File rootDir = (file.isAbsolute()) ? file : new File(_root, rootDirPath);
+			File rootDir = (file.isAbsolute()) ? file : new File(currentDir, rootDirPath);
 			if (rootDir.exists() && rootDir.isDirectory()) {
 				_root = rootDir;
 			} else {
@@ -188,8 +255,12 @@
 			}
 		}
 	}
-
+	
 	void write(SourceCode bcls) {
+		if (rootDirectory == null) {
+			bcls.write(System.out);
+			return;
+		}
 		File classFile = getClassFile(bcls);
 		if (_log.isInfoEnabled()) {
 			_log.info(_loc.get("write-class", bcls.getClassName(), 
@@ -204,17 +275,57 @@
 	
 	public static void main(String[] args) throws Exception {
 		Options options = new Options();
-		options.setFromCmdLine(args);
-		SDO2POJOGenerator test = new SDO2POJOGenerator();
+		args = options.setFromCmdLine(args);
+		
+		Flags flags = new Flags();
+		flags.annotate        = options.removeBooleanProperty("annotate", "anno", flags.annotate);
+		flags.generateMapping = options.removeBooleanProperty("generateORM", "map", flags.generateMapping);
+		flags.mappingFile     = options.removeProperty("mappingFile", flags.mappingFile);
+		flags.mergeUnit       = options.removeBooleanProperty("mergeUnit", "mergeUnit", flags.mergeUnit);
+		flags.rootDir         = options.removeProperty("rootDir", "d", flags.rootDir);
+		
+		SDO2POJOGenerator test = new SDO2POJOGenerator(flags);
+		
 		Options extra = options.setInto(test);
 		if (!extra.isEmpty())
 			throw new RuntimeException("Unrecognized options " + extra);
-		for (int i=options.size()*2; i<args.length; i++) {
+		
+		for (int i=0; args!=null && i<args.length; i++) {
 			List<Type> types = test.findTypes(args[i]);
 			for (Type type:types) {
-				test.getJavaClass(type);
+				if (!ImplHelper.isContainer(type))
+					test.getJavaClass(type);
 			}
 		}
+		if (test.pUnit != null) {
+			ClassLoader loader = Thread.currentThread().getContextClassLoader();
+			test._log.info(_loc.get("punit-save", Files.getFile("META-INF/persistence.xml", loader).getAbsolutePath()));
+			test.pUnit.save(Files.getOutputStream("META-INF/persistence.xml", loader));
+		}
+	}
+	
+	public static class Flags {
+		/**
+		 * Annotate generated classes 
+		 */
+		public boolean annotate        = true;
+		/**
+		 * Generate mapping file
+		 */
+		public boolean generateMapping = false;
+		/**
+		 * Name of the mapping file
+		 */
+		public String mappingFile = null;
+		
+		/**
+		 * Merge generated class names in persistence.xml
+		 */
+		public boolean mergeUnit = true;
+		
+		public String rootDir = null;
+		
+		public String logLevel = "INFO";
 	}
 
 }

Modified: labs/fluid/src/main/java/org/apache/openjpa/code/SourceCode.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/main/java/org/apache/openjpa/code/SourceCode.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/main/java/org/apache/openjpa/code/SourceCode.java (original)
+++ labs/fluid/src/main/java/org/apache/openjpa/code/SourceCode.java Sun Jul 22 20:57:08 2007
@@ -22,90 +22,92 @@
 import java.io.PrintStream;
 import java.util.*;
 
+import org.apache.openjpa.lib.util.Localizer;
+
 /**
  * Eases writing Java Source code.
  * 
- * @author ppoddar
+ * @author Pinaki Poddar
  *
  */
 public class SourceCode {
+	private static Localizer _loc = Localizer.forPackage(SourceCode.class);
+	
 	/**
-	 * List of Java Keywords populated statically
+	 * List of Java Keywords. Populated statically.
 	 */
 	private static final ArrayList<String> reserved = new ArrayList<String>();
+	private static final ArrayList<String> knownTypes = new ArrayList<String>();
 	private static final ArrayList<String> classQualifiers = new ArrayList<String>();
 	private static final ArrayList<String> fieldQualifiers = new ArrayList<String>();
 	private static final ArrayList<String> methodQualifiers = new ArrayList<String>();
 	
-	private static final int TABSIZE = 4;
-	private static final String SPACE = " ";
-	private static final String BLANK = "";
-	private static final String SEMICOLON = ";";
-	private static final String OPEN_BRACKET = "{";
-	private static final String CLOSE_BRACKET = "}";
-	private static final String NEWLINE = "\r\n";
+	private static final int TABSIZE          = 4;
+	private static final String SPACE         = " ";
+	private static final String BLANK         = "";
+	private static final String SEMICOLON     = ";";
+	private static final String BLOCK_START   = "{";
+	private static final String BLOCK_END     = "}";
+	private static final String BRACKET_START = "(";
+	private static final String BRACKET_END   = ")";
+	private static final String NEWLINE       = "\r\n";
 	
 	private Package pkg;
-	private Class  cls;
+	private Class   cls;
 	private Set<Import> imports = new TreeSet<Import>();
 	private Set<Field> fields   = new TreeSet<Field>();
 	private Set<Method> methods = new TreeSet<Method>();
 	
-	public SourceCode() {
-	}
-	
-	public SourceCode(String c) {
-		setClass(c);
-	}
+	public static final String EMPTY_STRING = "";
 	
+	/**
+	 * Create source code for a top-level class with given package and given
+	 * name. 
+	 * @param pkg can be null or empty to denote default package.
+	 * @param c name of the class.
+	 */
 	public SourceCode(String pkg, String c) {
 		setPackage(pkg);
 		setClass(c);
 	}
 	
+	/**
+	 * Get the fully qualified class name.
+	 */
+	public String getFullClassName() {
+		return getPackageName()+"."+cls.name;
+	}
+	
 	public String getClassName() {
 		return cls.name;
 	}
 	
+	/**
+	 * Get the package name.
+	 * Default package is represented as empty String.
+	 */
 	public String getPackageName() {
-		return (pkg==null) ? "" : pkg.name;
+		return (pkg==null) ? EMPTY_STRING : pkg.name;
 	}
 	
-	public Class getRoot() {
+	public Class getTopLevelClass() {
 		return cls;
 	}
 	
 	/**
-	 * Add a import statement.
-	 * 
-	 * @param i a non-null package import without <code>import</code> keyword.
-	 * For example <code>java.util.*</code> or <code>java.io.PrintStream</code>.
-	 * But <code>com.catch.me</code> is invalid because <code>catch</code> is
-	 * a reserved Java keyword. 
-	 * 
-	 */
-	public void addImport(String i) {
-		String pkgName = extractPackageName(i);
-		if ("java.lang".equals(pkgName))
-			return;
-		if (pkg != null && pkg.name.equals(pkgName))
-			return;
-		Import imp = new Import(i);
-		imports.add(imp);
-	}
-	
-	/**
 	 * Set a package statement. Can only be called once.
 	 * 
 	 * @param p a valid package without <code>package</code> keyword.
-	 * For example <code>com.</code> or <code>java.io.PrintStream</code>.
+	 * For example <code>com.acme</code> or <code>java.io.PrintStream</code>.
 	 * But <code>com.catch.me</code> is invalid because <code>catch</code> is
 	 * a reserved Java keyword. 
 	 * 
 	 */
-	public SourceCode setPackage(String p) {
+	private SourceCode setPackage(String p) {
 		if (pkg != null)
-			throw new IllegalStateException("Package is already set to " + pkg);
+			throw new IllegalStateException(_loc.get("pkg-set",pkg.name, p).toString());
+		if (!isValidPackageName(p)) 
+			throw new IllegalArgumentException(_loc.get("invalid-pkg",p).toString());
 		this.pkg = new Package(p);
 		return this;
 	}
@@ -116,35 +118,66 @@
 	 * @param c a valid class name without <code>class</code> keyword.
 	 * 
 	 */
-	public Class setClass(String c) {
+	private Class setClass(String c) {
 		if (cls != null)
-			throw new IllegalStateException("Class is already set to " + c);
-		String pkgName = extractPackageName(c);
-		String clsName = extractClassName(c);
-		if (pkgName != null) setPackage(pkgName);
-		assertValid(clsName);
-		this.cls = new Class(clsName);
+			throw new IllegalStateException(_loc.get("cls-set",cls.name,c).toString());
+		if (!isValidToken(c)) {
+			throw new IllegalArgumentException(_loc.get("invalid-cls",c).toString());
+		}
+		this.cls = new Class(c);
 		
 		return this.cls;
 	}
 	
 	/**
+	 * Add a import statement.
+	 * 
+	 * @param i a non-null package import without <code>import</code> keyword.
+	 * For example <code>java.util.*</code> or <code>java.io.PrintStream</code>.
+	 * But <code>com.catch.me</code> is invalid because <code>catch</code> is
+	 * a reserved Java keyword. 
+	 * 
+	 */
+	public boolean addImport(String i) {
+		if (isEmpty(i))
+			return false;
+		if (!isValidImportName(i))
+			throw new IllegalArgumentException(_loc.get("invalid-import",i).toString());
+		String pkgName = extractPackageName(i);
+		if ("java.lang".equals(pkgName))
+			return false;
+		if (pkg != null && pkg.name.equals(pkgName))
+			return false;
+		Import imp = new Import(i);
+		return imports.add(imp);
+	}
+	
+	/**
 	 * Set a field declaration. 
 	 * 
 	 * @param f a valid field name.
 	 * @param type is a valid name of declared type of the field.
+	 * If the type name is fully-qualified class name, then the package is
+	 * added to the import.
+	 * If the type name uses generic style e.g. <code>java.util.List&lt;Item&gt;</code>
+	 * then the type is used as it is and no import statement is added.
 	 * 
 	 */
 	public Field addField(String f, String type) {
-		assertValid(f);
-		addImport(type);
+		if (isEmpty(f) || !isValidToken(f)) {
+			throw new IllegalArgumentException(_loc.get("invalid-field-name",f).toString());
+		}
+		if (!isValidTypeName(type)) 
+			throw new IllegalArgumentException(_loc.get("invalid-field-type",f, type).toString());
 		Field field = new Field(f, extractClassName(type));
 		if (!fields.add(field))
-			throw new IllegalArgumentException("Duplicate field " + f);
-		addImport(type);
+			throw new IllegalArgumentException(_loc.get("duplicate-field",field, this).toString());
 		return field;
 	}
 	
+	/**
+	 * Adds getters and setters to every non-public field.
+	 */
 	public SourceCode markAsBean() {
 		for (Field f:fields)
 			f.markAsBean();
@@ -158,11 +191,16 @@
 	 * @param ret is a valid name of return type of the method.
 	 * 
 	 */
-	public Method addMethod(String m, String ret) {
-		assertValid(m);
-		Method method = new Method(m, ret);
+	public Method addMethod(String m, String retType) {
+		if (isEmpty(m) || !isValidToken(m)) {
+			throw new IllegalArgumentException(_loc.get("invalid-method",m).toString());
+		}
+		if (!isValidTypeName(retType)) {
+			throw new IllegalArgumentException(_loc.get("invalid-ret-type",retType,m).toString());
+		}
+		Method method = new Method(m, retType);
 		if (!methods.add(method)) 
-			throw new IllegalArgumentException("Duplicate method " + method);
+			throw new IllegalArgumentException(_loc.get("duplicate-method",method, this).toString());
 		return method;
 	}
 	
@@ -179,37 +217,93 @@
 			field.write(out, 1);
 		for (Method method:methods) 
 			method.write(out, 1);
-		out.println(CLOSE_BRACKET);
+		out.println(BLOCK_END);
 	}
 	
+	/**
+	 * Outputs <code>tab</code> number of spaces.
+	 */
 	static void tab(PrintStream out, int tab) {
 		for (int i=0; i<tab*TABSIZE; i++) {
 			out.print(SPACE);
 		}
 	}
 	
-	static void writeList(PrintStream out, String header, List list) {
-		if (list == null || list.isEmpty())
+	static void writeList(PrintStream out, String header, List list, boolean bracket) {
+		if (list == null || list.isEmpty()) {
+			if (bracket) out.append(BRACKET_START+BRACKET_END);
 			return;
+		}
 		out.append(header);
+		if (bracket) out.append(BRACKET_START);
 		for (int i=0; i<list.size(); i++) {
 			out.append(list.get(i).toString());
 			if (i!=list.size()-1) out.append(", ");
 		}
+		if (bracket) out.append(BRACKET_END);
 	}
 	
 	static String capitalize(String s) {
 		return Character.toUpperCase(s.charAt(0))+s.substring(1);
 	}
 	
-	static void assertValid(String s) {
-		if (reserved.contains(s))
-			throw new IllegalArgumentException(s + " is a Java keyword");
-		if (!isJavaIdentifier(s))
-			throw new IllegalArgumentException(s + " is not valid Java identifier");
+	/**
+	 * Affirms if given String is a valid import name.
+	 * Valid import names is either empty String or chain of valid name tokens
+	 * separtated by '.'. The last token can be '*'.
+	 */
+	public static boolean isValidImportName(String s) {
+		String pkg = extractPackageName(s);
+		String cls = extractClassName(s);
+		return isValidPackageName(pkg) && ("*".equals(cls) || isValidToken(cls));
+	}
+	
+	/**
+	 * Affirms if given String is a valid package name.
+	 * Valid package names is either empty String or chain of valid name tokens
+	 * separtated by '.'
+	 */
+	public static boolean isValidPackageName(String s) {
+		if (isEmpty(s)) return true;
+		LinkedList<String> tokens = tokenize(s, ".");
+		for (String token:tokens) {
+			if (!isValidToken(token))
+				return false;
+		}
+		return !s.endsWith(".");
+	}
+	
+	public static boolean isValidTypeName(String s) {
+		boolean isGeneric = s.endsWith(">") && 
+		                    s.indexOf("<")!=1 && 
+		                    s.indexOf("<")==s.lastIndexOf("<") && // once
+		                    s.indexOf(">")==s.lastIndexOf(">"); /// once
+		
+		if (isGeneric) {
+			String cls = s.substring(0, s.indexOf("<"));
+			String gen = s.substring(s.indexOf("<")+1,s.indexOf(">"));
+			return true;
+			
+		} else {
+			String pkg = extractPackageName(s);
+			String cls = extractClassName(s);
+			return isValidPackageName(pkg) && (isValidToken(cls) || isKnownType(cls));
+		}
+	}
+
+	static boolean isValidToken(String s) {
+		return !reserved.contains(s) && isJavaIdentifier(s);
+	}
+	
+	static boolean isKnownType(String s) {
+		return knownTypes.contains(s);
 	}
 	
-	static LinkedList<String> tokenize(String s, String delim) {
+	public static boolean isEmpty(String s) {
+		return s == null || s.length()==0;
+	}
+	
+	private static LinkedList<String> tokenize(String s, String delim) {
 		StringTokenizer tokenizer = new StringTokenizer(s, delim, false);
 		LinkedList<String> tokens = new LinkedList<String>();
 		while (tokenizer.hasMoreTokens())
@@ -230,6 +324,7 @@
         return true;
     }
 	
+	
 	public static String extractPackageName(String c) {
 		int i = c.lastIndexOf('.');
 		return (i == -1) ? null : c.substring(0,i);
@@ -253,7 +348,6 @@
 		private List<Annotation> annos = new ArrayList<Annotation>();
 		
 		public Element(String n, String t) {
-			assertValid(n);
 			name = n;
 			type = t;
 		}
@@ -286,6 +380,7 @@
 			return name.compareTo(other.name);
 		}
 		
+
 		public T makePublic() {
 			return addQualifier("public");
 		}
@@ -342,8 +437,8 @@
 			out.print("class "+ name + SPACE);
 			if (superCls!=null)
 				out.print("extends " + superCls + SPACE);
-			writeList(out, "implements ", interfaces);
-			out.println(SPACE + OPEN_BRACKET);
+			writeList(out, "implements ", interfaces, false);
+			out.println(SPACE + BLOCK_START);
 		}
 		
 		protected List<String> getValidQualifiers() {
@@ -372,6 +467,7 @@
 		
 		public Field addGetter() {
 			Method getter = new Method("get"+ capitalize(name), type);
+			getter.makePublic();
 			getter.addCodeLine("return "+ name);
 			SourceCode.this.methods.add(getter);
 			return this;
@@ -379,6 +475,7 @@
 		
 		public Field addSetter() {
 			Method setter = new Method("set"+ capitalize(name), "void");
+			setter.makePublic();
 			setter.addArgument(type, name);
 			setter.addCodeLine("this."+ name + " = "+ name);
 			SourceCode.this.methods.add(setter);
@@ -436,18 +533,18 @@
 		}
 		
 		public void write(PrintStream out, int tab) {
+			out.println(BLANK);
 			super.write(out, tab);
 			
-			out.print(type + SPACE + name + "(");
-			writeList(out, BLANK, args);
-			out.append(") ");
-			out.append(OPEN_BRACKET + SPACE + NEWLINE);
+			out.print(type + SPACE + name);
+			writeList(out, BLANK, args, true);
+			out.append(BLOCK_START + SPACE + NEWLINE);
 			for (String line:codeLines) {
 				tab(out, tab+1);
 				out.append(line).append(SEMICOLON).append(NEWLINE);
 			}
 			tab(out, tab);
-			out.append(CLOSE_BRACKET).append(NEWLINE);
+			out.append(BLOCK_END).append(NEWLINE);
 		}
 		
 		public boolean equals(Object other) {
@@ -467,15 +564,10 @@
 	 * Represents <code>import</code> statement.
 	 *
 	 */
-	public static class Import  implements Comparable<Import> {
+	static class Import  implements Comparable<Import> {
 		private String name;
 		
 		public Import(String name) {
-			String trunk = name;
-			if (name.endsWith(".*"))
-				trunk = name.substring(0,name.length()-2);
-			LinkedList<String> tokens = tokenize(trunk, ".");
-			for (String t:tokens) assertValid(t);
 			this.name = name;
 		}
 		public int compareTo(Import other) {
@@ -524,7 +616,8 @@
 		Annotation(String n) {
 			name = n;
 		}
-		public void put(String n, String v) {
+		
+		public void addProperty(String n, String v) {
 			nv.put(n, v);
 		}
 		
@@ -540,19 +633,16 @@
 				out.print(key+"="+nv.get(key));
 			}
 			out.println(")");
-			
 		}
-		
 	}
 	
-	public static class Package {
+	static class Package {
 		private String name;
 		
 		Package(String p) {
-			List<String> tokens = tokenize(p, ".");
-			for (String t:tokens) assertValid(t);
 			name = p;
 		}
+		
 		public void write(PrintStream out, int tab) {
 			out.println("package " + name + SEMICOLON);
 		}
@@ -609,6 +699,18 @@
 		reserved.add("native");
 		reserved.add("super");
 		reserved.add("while");
+		
+		knownTypes.add("boolean");
+		knownTypes.add("byte");
+		knownTypes.add("char");
+		knownTypes.add("double");
+		knownTypes.add("float");
+		knownTypes.add("int");
+		knownTypes.add("long");
+		knownTypes.add("short");
+		knownTypes.add("void");
+		knownTypes.add("String");
+		
 		
 		classQualifiers.add("abstract");
 		classQualifiers.add("private");

Modified: labs/fluid/src/main/java/org/apache/openjpa/sdo/ImplHelper.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/main/java/org/apache/openjpa/sdo/ImplHelper.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/main/java/org/apache/openjpa/sdo/ImplHelper.java (original)
+++ labs/fluid/src/main/java/org/apache/openjpa/sdo/ImplHelper.java Sun Jul 22 20:57:08 2007
@@ -19,6 +19,7 @@
 package org.apache.openjpa.sdo;
 
 import java.lang.reflect.Method;
+import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
 
@@ -66,10 +67,11 @@
 		} 
 	}
 	
-	public static String getClassName(Type type) {
-		return getPackageName(type) + "." + type.getName();
+	public static String getFullClassName(Type type) {
+		String pkg = getPackageName(type);
+		return (pkg==null || pkg.equals("")) ? type.getName() 
+				: pkg + "." + type.getName();
 	}
-
 	
 	public static String getPackageName(Type type) {
 		String result = "";
@@ -83,6 +85,30 @@
 			}
 		}
 		return result;
+	}
+	
+	/**
+	 * Affirms if this type has one and only one property and that property
+	 * type is not a basic data type and the property is many-valued.
+	 */
+	public static boolean isContainer(Type type) {
+		List properties = type.getProperties();
+		if (properties.size()==1) {
+			Property p = (Property)properties.get(0);
+			return !p.getType().isDataType() && p.isMany();
+		}
+		return false;
+	}
+	
+	/**
+	 * If the given type is a container type then return the type of its one 
+	 * and only one property. Otherwise null.
+	 */
+	public static Type getComponentType(Type type) {
+		if (isContainer(type)) {
+			return ((Property)type.getProperties().get(0)).getType();
+		}
+		return null;
 	}
 	
 	private static boolean isEMFImplementaionAvailable() {

Modified: labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManager.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManager.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManager.java (original)
+++ labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManager.java Sun Jul 22 20:57:08 2007
@@ -23,6 +23,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -40,7 +41,7 @@
  * A specialized EntityManager that accepts SDO DataObject/DataGraph as 
  * arguments for persistence operation.
  * <br>
- * Cirrently only supports persist() and createQuery()
+ * Currently only supports persist() and createQuery()
  * 
  * @author Pinaki Poddar
  *
@@ -49,11 +50,13 @@
 	// TODO: Change to a smarter cache
 	private Map<DataObject, Object> cache = new HashMap<DataObject, Object>();
 	
-	private SDOTypeRepository repos;
+	private SDOMetaDataFactory factory;
 		
 	public SDOEntityManager(SDOEntityManagerFactory emf, Broker broker) {
 		super(emf, broker);
-		repos = emf.getTypeRepository();
+		factory = (SDOMetaDataFactory)emf.getConfiguration()
+			.getMetaDataRepositoryInstance()
+			.getMetaDataFactory();
 	}
 	
 	public void persist(Object o) {
@@ -93,7 +96,7 @@
 			return closure;
 		
 		try {
-			Class cls = repos.getJavaClass(type, true);
+			Class cls = factory.getJavaClass(type, true);
 			pc = cls.newInstance();
 			cache.put(dataObject, pc);
 			closure.put(dataObject, pc);
@@ -106,8 +109,25 @@
 				} 
 				Object value = dataObject.get(property);
 				String methodName = ImplHelper.getMethodName("set",property);
-				if (!propertyType.isDataType()) {
-					if (property.isMany()) {
+				if (propertyType.isDataType()) {
+					Method setter = cls.getMethod(methodName, value.getClass());
+					setter.invoke(pc, value);
+				} else if (ImplHelper.isContainer(propertyType)) {
+					Class componentClass = factory.getJavaClass(ImplHelper.getComponentType(propertyType), true);
+					DataObject container = (DataObject)value;
+					Property elementProperty = (Property)container.getInstanceProperties().get(0);
+					Iterator dataList = container.getList(elementProperty).iterator();
+//					Iterator dataList = dataObject.getList(property).iterator();
+					List objList  = new ArrayList();
+					for (;dataList.hasNext();) {
+						DataObject dataElement = (DataObject)dataList.next();
+						closure = convertAndtraverse(dataElement, closure);
+						objList.add(closure.get(dataElement));
+					}
+					value = objList;
+					Method setter = cls.getMethod(methodName, List.class);
+					setter.invoke(pc, value);
+				} else if (property.isMany()) {
 						List dataList = (List)value;
 						List objList  = new ArrayList();
 						for (Object o:dataList) {
@@ -123,11 +143,8 @@
 						Method setter = cls.getMethod(methodName, value.getClass());
 						setter.invoke(pc, value);
 					}
-				} else {
-					Method setter = cls.getMethod(methodName, value.getClass());
-					setter.invoke(pc, value);
-				}
-			}
+				} 
+			
 		} catch (Exception e) {
 			throw new RuntimeException(e);
 		}
@@ -138,7 +155,7 @@
 	DataObject createDataObject(Object pc) {
 		if (pc == null)
 			return null;
-		Type type = repos.getSDOType(pc.getClass(), false);
+		Type type = factory.getSDOType(pc.getClass(), true);
 		if (type == null) {
 			return null;
 		}
@@ -146,9 +163,20 @@
 		List properties = dataObject.getInstanceProperties();
 		for (Object o:properties) {
 			Property property = (Property)o;
+			Type propertyType = property.getType();
 			Object value = ImplHelper.getFieldValue(property, pc);
-			if (property.getType().isDataType()) {
+			if (propertyType.isDataType()) {
 				dataObject.set(property, value);
+			} else if (ImplHelper.isContainer(propertyType)) {
+				List olist = (List)value;
+				DataObject container = dataObject.createDataObject(property);
+				List<DataObject> dlist = new ArrayList<DataObject>();
+				for (Object e:olist) {
+					DataObject d = createDataObject(e);
+					if (d != null) 
+						dlist.add(d);
+				}
+				container.setList(0, dlist);
 			} else if (property.isMany()) {
 				List olist = (List) value;
 				List dlist = (List)dataObject.get(property);

Modified: labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManagerFactory.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManagerFactory.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManagerFactory.java (original)
+++ labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOEntityManagerFactory.java Sun Jul 22 20:57:08 2007
@@ -44,15 +44,15 @@
     	super(factory);
     }
     
-    public SDOTypeRepository getTypeRepository() {
-    	if (repos == null) {
-    		OpenJPAConfiguration conf = getConfiguration();
-    		SDOMetaDataFactory factory = (SDOMetaDataFactory)conf
-    			.getMetaDataRepositoryInstance().getMetaDataFactory();
-    		repos = new SDOTypeRepository(conf, factory);
-    	}
-    	return repos;
-    }
+//    public SDOTypeRepository getTypeRepository() {
+//    	if (repos == null) {
+//    		OpenJPAConfiguration conf = getConfiguration();
+//    		SDOMetaDataFactory factory = (SDOMetaDataFactory)conf
+//    			.getMetaDataRepositoryInstance().getMetaDataFactory();
+//    		repos = new SDOTypeRepository(conf, factory);
+//    	}
+//    	return repos;
+//    }
 	
     /**
      * Create a new entity manager around the given broker.

Modified: labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOMetaDataFactory.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOMetaDataFactory.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOMetaDataFactory.java (original)
+++ labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOMetaDataFactory.java Sun Jul 22 20:57:08 2007
@@ -19,48 +19,122 @@
 package org.apache.openjpa.sdo;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.enhance.PersistenceCapable;
 import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.log.Log;
 import org.apache.openjpa.lib.meta.ClassArgParser;
+import org.apache.openjpa.lib.util.Localizer;
 import org.apache.openjpa.persistence.PersistenceMetaDataFactory;
+import org.apache.openjpa.util.InternalException;
+
+import commonj.sdo.Type;
 
 /**
- * A specialized MetaDataFactory to process XML Schema based SDO MetaModel
- * to dynamically generate Java classes.
+ * A specialized MetaDataFactory to process XML Schema based SDO MetaModel.
+ * 
  * 
- * @author ppoddar
+ * @author Pinaki Poddar
  *
  */
 public class SDOMetaDataFactory extends PersistenceMetaDataFactory {
+	private static final Localizer _loc = Localizer.forPackage(SDOMetaDataFactory.class);
 	private OpenJPAConfiguration conf;
 	private String resources;
 	private List<String> resourceList;
-	private SDOTypeRepository sdoRepository;
+	private SDOTypeParser sdoTypeParser;
 	private Set<String> _typeNames = new HashSet<String>();
-	
+	private Log _log;
+	private Map<Type, Class> _cache = new HashMap<Type, Class>();
+	private Map<Class, Type> _rcache = new HashMap<Class, Type>();
+
 	@Override
 	public void setConfiguration(Configuration conf) {
 		super.setConfiguration(conf);
 		this.conf = (OpenJPAConfiguration)conf;
+		_log = this.conf.getLog(OpenJPAConfiguration.LOG_METADATA);
 	}
 	
 	@Override
 	public ClassArgParser newClassArgParser() {
-		return getSDOTypeRepository();
+		return getSDOTypeParser();
+	}
+	
+	public SDOTypeParser getSDOTypeParser() {
+		if (sdoTypeParser == null) {
+			sdoTypeParser = new SDOTypeParser(conf);
+		}
+		return sdoTypeParser;
+	}
+	
+	void cache(Type type, Class cls) {
+		if (!isEnhanced(cls)) {
+			throw new InternalException(_loc.get("cache-unenhanced", 
+					cls.getName(), cls.getClassLoader()).toString());
+		}
+		if (_log.isTraceEnabled())
+			_log.trace(_loc.get("cache-sdo-type", type.getName(), cls.getName(), 
+					cls.getClassLoader()).toString());
+		_cache.put(type, cls);
+		_rcache.put(cls, type);
+	}
+
+	/**
+	 * Get the Java Class corresponding to the given type.
+	 */
+	public Class getJavaClass(Type type, boolean mustExist) {
+		Class cls = _cache.get(type);
+		if (cls != null)
+			return cls;
+		
+		String fullName = ImplHelper.getFullClassName(type);
+		try {
+			cls = Class.forName(fullName);
+			if (cls != null && isEnhanced(cls)) {
+				if (_log.isInfoEnabled())
+					_log.info(_loc.get("found-enhanced-cls", type.getName(), 
+							fullName, cls.getClassLoader().toString()));
+				repos.getMetaData(cls, cls.getClassLoader(), true);
+				cache(type, cls);
+			}
+		} catch (ClassNotFoundException ex) {
+			throw new RuntimeException("class not found " + fullName);
+		}
+		return cls;
 	}
 	
-	public SDOTypeRepository getSDOTypeRepository() {
-		if (sdoRepository == null) {
-			sdoRepository = new SDOTypeRepository(conf, this);
+	/**
+	 * Gets SDO Type corresponding to the given Java class.
+	 */
+	public Type getSDOType(Class cls, boolean mustExist) {
+		Type type = _rcache.get(cls);
+		if (type == null && mustExist) {
+			initialize();
+			type = _rcache.get(cls);
+			if (type == null) 
+				throw new RuntimeException(_loc.get("no-type-for-class",
+					cls.getName()).toString());
 		}
-		return sdoRepository;
+		return type;
 	}
 
+	void initialize() {
+		getPersistentTypeNames(true, null);
+		Set<Type> types = getSDOTypeParser().getParsedTypes();
+		for (Type type:types)
+			getJavaClass(type, false);
+	}
 	
+	boolean isEnhanced(Class cls) {
+		return PersistenceCapable.class.isAssignableFrom(cls);
+	}
+
 	public void setResources(String resources) {
 		this.resources = resources;
 	}
@@ -84,7 +158,7 @@
     	if (resourceList == null || resourceList.isEmpty()) 
     		return _typeNames;
     	for (String resource:resourceList) {
-    		String[] names = getSDOTypeRepository().parseTypeNames(resource);
+    		String[] names = getSDOTypeParser().parseTypeNames(resource);
     		for (String name:names)
     			addPersistentTypeNames(name);
     	}

Modified: labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOTypeRepository.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOTypeRepository.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOTypeRepository.java (original)
+++ labs/fluid/src/main/java/org/apache/openjpa/sdo/SDOTypeRepository.java Sun Jul 22 20:57:08 2007
@@ -100,8 +100,8 @@
 		this.conf = c;
 		_log = conf.getLog(OpenJPAConfiguration.LOG_METADATA);
 		this.repos = conf.getMetaDataRepositoryInstance();
-		repos.setValidate(MetaDataRepository.VALIDATE_NONE);
-		repos.setSourceMode(MetaDataRepository.MODE_META);
+//		repos.setValidate(MetaDataRepository.VALIDATE_NONE);
+//		repos.setSourceMode(MetaDataRepository.MODE_META);
 
 		this.factory = factory;
 		resolver = conf.getClassResolverInstance();
@@ -123,6 +123,7 @@
 		}
 		return transformer;
 	}
+	
 	/**
 	 * Get a Java class corresponding to a SDO Type. Dynamically generate the
 	 * Java class if it does not exist and <code>mustExist</code> is true.
@@ -134,28 +135,30 @@
 		if (cls != null)
 			return cls;
 		
+		String fullName = ImplHelper.getFullClassName(type);
 		try {
-			cls = Class.forName(ImplHelper.getClassName(type));
+			cls = Class.forName(fullName);
 			if (cls != null && isEnhanced(cls)) {
 				if (_log.isInfoEnabled())
 					_log.info(_loc.get("found-enhanced-cls", type.getName(), 
-							cls.getName(), cls.getClassLoader().toString()));
+							fullName, cls.getClassLoader().toString()));
+				repos.getMetaData(cls, cls.getClassLoader(), true);
 				cache(type, cls);
 			}
 		} catch (ClassNotFoundException ex) {
-			// ignore;
-		}
-		if (cls == null) {
-			cls = createClass(type);
-			if (cls == null && mustExist) {
-				throw new RuntimeException(_loc.get("no-class-for-type",
-						type.getName()).toString());
-			} else {
-				_log.info(_loc.get("register-sdo", cls.getName(), 
-						cls.getClassLoader()));
-				cache(type, cls);
-			}
+			throw new RuntimeException("class not found " + fullName);
 		}
+//		if (cls == null) {
+//			cls = createClass(type);
+//			if (cls == null && mustExist) {
+//				throw new RuntimeException(_loc.get("no-class-for-type",
+//						type.getName()).toString());
+//			} else {
+//				_log.info(_loc.get("register-sdo", cls.getName(), 
+//						cls.getClassLoader()));
+//				cache(type, cls);
+//			}
+//		}
 		return cls;
 	}
 
@@ -182,7 +185,7 @@
 	Class createClass(Type type) {
 		Class cls = null; 
 		try {
-			cls = Class.forName(ImplHelper.getClassName(type));
+			cls = Class.forName(ImplHelper.getFullClassName(type));
 			if (isEnhanced(cls)) {
 				return cls;
 			}
@@ -197,7 +200,7 @@
 	}
 
 	private Class generateEnhancedClass(Type type) {
-		String javaClassName = ImplHelper.getClassName(type);
+		String javaClassName = ImplHelper.getFullClassName(type);
 		if (enhancedProject.containsClass(javaClassName)) {
 			return enhancedProject.loadClass(javaClassName).getType();
 		}
@@ -459,7 +462,7 @@
 		List<Type> types = findTypes(resource);
 		List<String> result = new ArrayList<String>();
 		for (Type type : types) {
-			result.add(ImplHelper.getClassName(type));
+			result.add(ImplHelper.getFullClassName(type));
 		}
 		return (String[])result.toArray(new String[result.size()]);
 	}
@@ -475,16 +478,23 @@
 			}
 			return result;
 		}
-		List types = XSDHelper.INSTANCE.define(xsdInputStream, null);
-
-		for (Object t : types) {
-			if (t instanceof Type == false)
-				continue;
-			Type type = (Type) t;
-			if (type.isDataType() || "DocumentRoot".equals(type.getName()))
-				continue;
-
-			result.add(type);
+		try {
+			List types = XSDHelper.INSTANCE.define(xsdInputStream, null);
+			for (Object t : types) {
+				if (t instanceof Type == false)
+					continue;
+				Type type = (Type) t;
+				if (type.isDataType() || "DocumentRoot".equals(type.getName()))
+					continue;
+	
+				result.add(type);
+			}
+		} finally {
+			try {
+				xsdInputStream.close();
+			} catch (IOException e) {
+				//ignore
+			}
 		}
 		return result;
 	}

Modified: labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties
URL: http://svn.apache.org/viewvc/labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties (original)
+++ labs/fluid/src/main/resources/org/apache/openjpa/sdo/localizer.properties Sun Jul 22 20:57:08 2007
@@ -14,5 +14,6 @@
 write-class: Writing "{0}" to "{1}"
 wrong-root-dir: Property "{0}" value "{1}" is either does not exist or not a \
 	directory. The dynamic classes will be written to "{2}"
-xsd-not-found:Can not find "{0}" as resource in current classpath.
+xsd-not-found: Can not find "{0}" as resource in current classpath.
+repeat-parse: "{0}" has been parsed already for SDO types
 	

Added: labs/fluid/src/site/site.xml
URL: http://svn.apache.org/viewvc/labs/fluid/src/site/site.xml?view=auto&rev=558596
==============================================================================
--- labs/fluid/src/site/site.xml (added)
+++ labs/fluid/src/site/site.xml Sun Jul 22 20:57:08 2007
@@ -0,0 +1,5 @@
+<project name="Fluid">
+  <body>
+    <menu ref="reports"/>
+  </body>
+</project>
\ No newline at end of file

Added: labs/fluid/src/test/java/example/basic/TestCRUD.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/test/java/example/basic/TestCRUD.java?view=auto&rev=558596
==============================================================================
--- labs/fluid/src/test/java/example/basic/TestCRUD.java (added)
+++ labs/fluid/src/test/java/example/basic/TestCRUD.java Sun Jul 22 20:57:08 2007
@@ -0,0 +1,120 @@
+package example.basic;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
+import org.apache.openjpa.persistence.OpenJPAQuery;
+
+import commonj.sdo.DataObject;
+import commonj.sdo.helper.DataFactory;
+
+import test.common.AbstractSDOTest;
+
+public class TestCRUD extends AbstractSDOTest {
+	
+	private static final String SDO_MODEL_NAMESPACE  = "http://www.example.com/PO";
+
+	protected String getXSDResource() {
+		return "META-INF/po.xsd";
+	}
+
+	public String getPersistenceUnitName() {
+		return System.getProperty("persistence.unit", "test");
+	}
+
+	/**
+	 * Persist a DataObject. The operation should cascade to the closure of the
+	 * given DataObject.
+	 */
+	public void testPersist() {
+		DataObject purchaseOrder = createPurchaseOrder();
+		EntityManager em = emf.createEntityManager();
+		em.getTransaction().begin();
+		em.persist(purchaseOrder);
+		em.getTransaction().commit();
+	}
+
+	/**
+	 * Query using JPQL. The query results should be DataObjects. The related
+	 * DataObjects should also be fetched.
+	 */
+	public void testQuery() {
+		EntityManager em = emf.createEntityManager();
+		String jpql = "SELECT p FROM PurchaseOrderType p";
+		Query query = em.createQuery(jpql);
+		((OpenJPAQuery)query).getFetchPlan().addField("com.bea.sdo.domain.PurchaseOrderType.items");
+		List result = query.getResultList();
+		
+		for (Object o : result) {
+			assertTrue(o.getClass() + " is not DataObject", o instanceof DataObject);
+			DataObject dataObject = (DataObject) o;
+			assertEquals("PurchaseOrderType", dataObject.getType().getName());
+			String orderDate = dataObject.getString("orderDate");
+			assertEquals("1999-10-20", orderDate);
+			DataObject shipTo = (DataObject) dataObject.get("shipTo");
+			assertNotNull(shipTo);
+			assertEquals("Alice Smith", shipTo.get("name"));
+			
+			DataObject items = (DataObject)dataObject.get("items");
+			if (items == null) return;
+			List itemList = items.getList("item");
+			for (Object item:itemList) {
+				System.err.println("item: " + item);
+			};
+//			assertTrue(itemList.getClass() + " is not List", items instanceof List);
+		}
+	}
+	
+	
+	/**
+	 * Create a SDO MetaData Model from a XML Schema.
+	 * 
+	 */
+	DataObject createPurchaseOrder() {
+		DataObject purchaseOrder = DataFactory.INSTANCE.create(
+				SDO_MODEL_NAMESPACE, "PurchaseOrderType");
+
+		purchaseOrder.setString("orderDate", "1999-10-20");
+
+		DataObject shipTo = purchaseOrder.createDataObject("shipTo");
+		purchaseOrder.set("shipTo", shipTo);
+		shipTo.set("country", "US");
+		shipTo.set("name", "Alice Smith");
+		shipTo.set("street", "123 Maple Street");
+		shipTo.set("city", "Mill Valley");
+		shipTo.set("state", "CA");
+		shipTo.setString("zip", "90952");
+
+		 DataObject billTo = purchaseOrder.createDataObject("billTo");
+		 purchaseOrder.set("billTo", billTo);
+		 billTo.set("country", "US");
+		 billTo.set("name", "Robert Smith");
+		 billTo.set("street", "8 Oak Avenue");
+		 billTo.set("city", "Mill Valley");
+		 billTo.set("state", "PA");
+		 billTo.setString("zip", "95819");
+
+		 purchaseOrder.set("comment", "Hurry, my lawn is going wild!");
+
+		 DataObject items = purchaseOrder.createDataObject("items");
+		
+		 DataObject item1 = items.createDataObject("item");
+		 item1.set("partNum", "872-AA");
+		 item1.set("productName", "Lawnmower");
+		 item1.setInt("quantity", 1);
+		 item1.setString("USPrice", "148.95");
+		 item1.set("comment", "Confirm this is electric");
+		
+		 DataObject item2 = items.createDataObject("item");
+		 item2.set("partNum", "926-AA");
+		 item2.set("productName", "Baby Monitor");
+		 item2.setInt("quantity", 1);
+		 item2.setString("USPrice", "39.98");
+		 item2.setString("shipDate", "1999-05-21");
+
+		return purchaseOrder;
+
+	}
+}

Modified: labs/fluid/src/test/java/test/TestModel.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/test/java/test/TestModel.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/test/java/test/TestModel.java (original)
+++ labs/fluid/src/test/java/test/TestModel.java Sun Jul 22 20:57:08 2007
@@ -32,6 +32,8 @@
 import org.apache.openjpa.sdo.SDOEntityManager;
 import org.apache.openjpa.sdo.SDOEntityManagerFactory;
 
+import test.common.AbstractSDOTest;
+
 import commonj.sdo.DataObject;
 import commonj.sdo.Type;
 import commonj.sdo.helper.DataFactory;
@@ -95,6 +97,7 @@
 			assertEquals("Alice Smith", shipTo.get("name"));
 			
 			DataObject items = (DataObject)dataObject.get("items");
+			if (items == null) return;
 			List itemList = items.getList("item");
 			for (Object item:itemList) {
 				System.err.println("item: " + item);

Modified: labs/fluid/src/test/java/test/TestSDO.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/test/java/test/TestSDO.java?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/test/java/test/TestSDO.java (original)
+++ labs/fluid/src/test/java/test/TestSDO.java Sun Jul 22 20:57:08 2007
@@ -33,6 +33,8 @@
 import org.apache.tuscany.sdo.helper.HelperProviderImpl;
 import org.apache.tuscany.sdo.impl.ClassImpl;
 
+import test.common.AbstractSDOTest;
+
 import commonj.sdo.DataObject;
 import commonj.sdo.Type;
 import commonj.sdo.helper.DataFactory;
@@ -57,6 +59,10 @@
 		return "META-INF/po.xsd";
 	}
 
+	public String getPersistenceUnitName() {
+		// does not require JPA
+		return null;
+	}
 
 	public Type getType(String name) {
 		for (Type t:sdoTypes) {

Added: labs/fluid/src/test/java/test/TestSourceCode.java
URL: http://svn.apache.org/viewvc/labs/fluid/src/test/java/test/TestSourceCode.java?view=auto&rev=558596
==============================================================================
--- labs/fluid/src/test/java/test/TestSourceCode.java (added)
+++ labs/fluid/src/test/java/test/TestSourceCode.java Sun Jul 22 20:57:08 2007
@@ -0,0 +1,109 @@
+package test;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.openjpa.code.SourceCode;
+import org.apache.openjpa.persistence.PersistenceProductDerivation;
+import org.apache.openjpa.persistence.PersistenceUnitInfoImpl;
+import org.apache.openjpa.persistence.PersistenceProductDerivation.ConfigurationProviderImpl;
+
+import junit.framework.TestCase;
+
+public class TestSourceCode extends TestCase {
+	public void testImport() {
+		assertTrue(SourceCode.isValidImportName("java.util.*"));
+		assertTrue(SourceCode.isValidImportName("java.util.List"));
+		assertFalse(SourceCode.isValidImportName("java.util."));
+		assertFalse(SourceCode.isValidImportName("com.catch.*."));
+		assertFalse(SourceCode.isValidImportName("com.catch.List"));
+	}
+	
+	public void testPackageName() {
+		assertTrue(SourceCode.isValidPackageName("java.util"));
+		assertFalse(SourceCode.isValidPackageName("java.util."));
+		assertFalse(SourceCode.isValidPackageName("java.util.*"));
+		assertFalse(SourceCode.isValidPackageName("com.catch"));
+		assertFalse(SourceCode.isValidPackageName("com.catch.*"));
+	}
+	
+	public void testTypeName() {
+		assertTrue(SourceCode.isValidTypeName("java.util.List"));
+		assertFalse(SourceCode.isValidTypeName("java.util.List.*"));
+		assertFalse(SourceCode.isValidTypeName(" java.util.List"));
+		assertTrue(SourceCode.isValidTypeName("java.util.List<Item>"));
+	}
+	
+	public void testWriteCode() {
+		SourceCode code = new SourceCode("com.bea.sdo", "TestClass");
+		code.addImport("java.util.*");
+		code.addImport("java.io.*");
+		
+		code.getTopLevelClass().addInterface("Serializable")
+		                       .addInterface("PC")
+		                       .setSuper("BaseEntity")
+		                       .addAnnotation("@Entity");
+		code.addField("x", "int")
+			.addQualifier("private")
+			.addGetter().addSetter()
+			.addAnnotation("@Basic")
+			.addProperty("fetch", "FetchType.LAZY");
+		
+		code.addField("y","String");
+		
+		code.addMethod("add", "int").addQualifier("public").addQualifier("static")
+		.addArgument("int", "a").addArgument("int", "b").
+		addCodeLine("int x=a+b").
+		addCodeLine("return x");
+		
+		code.write(System.out);
+	}
+	
+	public void testBeanCode() {
+		SourceCode code = new SourceCode("com.bea.sdo", "TestClass");
+		code.addImport("java.util.*");
+		code.addImport("java.io.*");
+		
+		code.getTopLevelClass().addInterface("Serializable")
+		                       .addInterface("PC")
+		                       .setSuper("BaseEntity")
+		                       .addAnnotation("@Entity");
+		code.addField("x", "int")
+			.addQualifier("private")
+			.addAnnotation("@Basic")
+			.addProperty("fetch", "FetchType.LAZY");
+		
+		code.addField("y","String");
+		code.markAsBean();
+		
+		code.write(System.out);
+	}
+	
+	public void testDuplicateField() {
+		SourceCode code = new SourceCode("some.pkg", "SomeClass");
+		try {
+			code.addField("a", "int");
+			code.addField("a", "float");
+			fail("Expected DuplicateField exception");
+		} catch (RuntimeException e) {
+			System.err.println("Caught expected " + e);
+		}
+	}
+	
+	public void testDuplicateMethod() {
+		SourceCode code = new SourceCode("some.pkg", "SomeClass");
+		try {
+			code.addMethod("add", "int").addQualifier("public").addQualifier("static")
+			.addArgument("int", "a").addArgument("int", "b");
+			code.addMethod("add", "float")
+			.addArgument("int", "a").addArgument("int", "b");
+			fail("Expected DuplicateField exception");
+		} catch (RuntimeException e) {
+			System.err.println("Caught expected " + e);
+		}
+	}
+}

Copied: labs/fluid/src/test/java/test/common/AbstractSDOTest.java (from r558139, labs/fluid/src/test/java/test/AbstractSDOTest.java)
URL: http://svn.apache.org/viewvc/labs/fluid/src/test/java/test/common/AbstractSDOTest.java?view=diff&rev=558596&p1=labs/fluid/src/test/java/test/AbstractSDOTest.java&r1=558139&p2=labs/fluid/src/test/java/test/common/AbstractSDOTest.java&r2=558596
==============================================================================
--- labs/fluid/src/test/java/test/AbstractSDOTest.java (original)
+++ labs/fluid/src/test/java/test/common/AbstractSDOTest.java Sun Jul 22 20:57:08 2007
@@ -16,78 +16,49 @@
  * specific language governing permissions and limitations
  * under the License.    
  */
-package test;
+package test.common;
 
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Set;
 
+import javax.persistence.EntityManagerFactory;
 import javax.persistence.Persistence;
 
+import org.apache.openjpa.lib.meta.ClassArgParser;
 import org.apache.openjpa.sdo.SDOEntityManagerFactory;
+import org.apache.openjpa.sdo.SDOTypeParser;
 
 import commonj.sdo.Type;
-import commonj.sdo.helper.XSDHelper;
 
 import junit.framework.TestCase;
 
-public class AbstractSDOTest extends TestCase {
+public abstract class AbstractSDOTest extends TestCase {
 	protected static SDOEntityManagerFactory emf;
-	protected static List<Type> sdoTypes;
+	protected static Set<Type> sdoTypes;
 	
-
 	/**
 	 * Obtain a EntityManagerFactory and initialize SDO Types.
 	 */
 	public void setUp() throws Exception {
 		String pUnit = getPersistenceUnitName();
 		if (pUnit !=null && emf == null) {
-			emf = (SDOEntityManagerFactory) Persistence
-					.createEntityManagerFactory(pUnit);
-		}
-		String xsdResource = getXSDResource();
-		if (xsdResource != null && sdoTypes == null) {
-			sdoTypes = initializeSDOTypes(xsdResource);
+			EntityManagerFactory tmp = Persistence.createEntityManagerFactory(pUnit);
+			assertNotNull(tmp);
+			assertTrue(tmp instanceof SDOEntityManagerFactory);
+			emf = (SDOEntityManagerFactory)tmp;
+			ClassArgParser parser = emf.getConfiguration().getMetaDataRepositoryInstance()
+				.getMetaDataFactory()
+				.newClassArgParser();
+			assertTrue(parser instanceof SDOTypeParser);
+			((SDOTypeParser)parser).parseTypeNames(getXSDResource());
+			sdoTypes = ((SDOTypeParser)parser).getParsedTypes();
 		}
 	}
 
 	/**
-	 * Get all the non-primitive SDO types defined in a given XML Schema.
-	 * 
+	 * Get the name of the persistence unit to be used by this receiver.
+	 * Return null if this test case does not use JPA.
 	 */
-	public List<Type> initializeSDOTypes(String resource) {
-		InputStream xsdInputStream = this.getClass().getClassLoader()
-				.getResourceAsStream(resource);
-		assertNotNull(resource + " not found", xsdInputStream);
-		String schemaLocation = null;
-
-		List<Type> result = new ArrayList<Type>();
-		try {
-			List types = XSDHelper.INSTANCE.define(xsdInputStream, schemaLocation);
-			for (Object t : types) {
-				if (t instanceof Type == false)
-					continue;
-				Type type = (Type) t;
-				if (type.isDataType() || "DocumentRoot".equals(type.getName()))
-					continue;
-				result.add((Type) t);
-			}
-			assertFalse("No SDO Type found in " + resource, result.isEmpty());
-		} finally {
-			try {
-				xsdInputStream.close();
-			} catch (Exception e) {
-				// ignore}
-			}
-		}
-		return result;
-	}
+	protected abstract String getPersistenceUnitName();
 	
-	protected String getPersistenceUnitName() {
-		return null;
-	}
-	
-	protected String getXSDResource() {
-		return null;
-	}
+	protected abstract String getXSDResource();
 }

Modified: labs/fluid/src/test/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/labs/fluid/src/test/resources/META-INF/persistence.xml?view=diff&rev=558596&r1=558595&r2=558596
==============================================================================
--- labs/fluid/src/test/resources/META-INF/persistence.xml (original)
+++ labs/fluid/src/test/resources/META-INF/persistence.xml Sun Jul 22 20:57:08 2007
@@ -1,27 +1,21 @@
-<persistence xmlns="http://java.sun.com/xml/ns/persistence"
-   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
-   version="1.0">
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="test">
-   		<class>a.b.c</class>
-   		<class>x.y</class>
-   		
+   <!--
+		<class>com.bea.sdo.domain.item</class>
+		<class>com.bea.sdo.domain.PurchaseOrderType</class>
+		<class>com.bea.sdo.domain.USAddress</class>
+	-->
 		<properties>
 			<property name="openjpa.EntityManagerFactory" value="sdo"/>
 			<property name="openjpa.MetaDataFactory" value="sdo(Resources=META-INF/po.xsd)"/>
 			<property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
-			<property name="openjpa.ConnectionURL"        value="jdbc:mysql://localhost/SDO2"/>
-			<property name="openjpa.ConnectionUserName"   value="root"/>
-			<property name="openjpa.ConnectionPassword"   value="hello"/>
-			
+			<property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost/SDO2"/>
+			<property name="openjpa.ConnectionUserName" value="root"/>
+			<property name="openjpa.ConnectionPassword" value="hello"/>
 			<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
-
-   			<property name="openjpa.sdo.DynamicClassDir" value="target/classes"/>
    			<property name="openjpa.QueryCompilationCache" value="false"/>
-   			<property name="openjpa.Log" value="DefaultLevel=WARN"/>
+   			<property name="openjpa.Log" value="DefaultLevel=TRACE"/>
       	</properties>
    </persistence-unit>
 </persistence>
-
-
-	
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org