cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject [02/17] cayenne git commit: CAY-2026 Java 7
Date Sat, 12 Sep 2015 10:02:30 GMT
http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
index 95f6d8e..4797b43 100644
--- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
+++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/EOModelProcessor.java
@@ -55,722 +55,720 @@ import org.apache.commons.logging.LogFactory;
  */
 public class EOModelProcessor {
 
-    private static final Log logger = LogFactory.getLog(EOModelProcessor.class);
-
-    protected Predicate prototypeChecker;
-
-    public EOModelProcessor() {
-        prototypeChecker = new Predicate() {
-
-            public boolean evaluate(Object object) {
-                if (object == null) {
-                    return false;
-                }
-
-                String entityName = object.toString();
-                return entityName.startsWith("EO") && entityName.endsWith("Prototypes");
-            }
-        };
-    }
-
-    /**
-     * @deprecated since 4.0 in favor of {@link #loadModeIndex(URL)}.
-     */
-    @Deprecated
-    public Map loadModeIndex(String path) throws Exception {
-        return loadModeIndex(new File(path).toURI().toURL());
-    }
-
-    /**
-     * Returns index.eomodeld contents as a Map.
-     * 
-     * @since 4.0
-     */
-    // TODO: refactor EOModelHelper to provide a similar method without loading
-    // all entity files in memory... here we simply copied stuff from
-    // EOModelHelper
-    public Map loadModeIndex(URL url) throws Exception {
-
-        String urlString = url.toExternalForm();
-
-        if (!urlString.endsWith(".eomodeld")) {
-            url = new URL(urlString + ".eomodeld");
-        }
-
-        Parser plistParser = new Parser();
-        InputStream in = new URL(url, "index.eomodeld").openStream();
-
-        try {
-            plistParser.ReInit(in);
-            return (Map) plistParser.propertyList();
-        } finally {
-            in.close();
-        }
-    }
-
-    /**
-     * @deprecated since 4.0 in favor of {@link #loadEOModel(URL)}.
-     */
-    @Deprecated
-    public DataMap loadEOModel(String path) throws Exception {
-        return loadEOModel(path, false);
-    }
-
-    /**
-     * @deprecated since 4.0 in favor of {@link #loadEOModel(URL, boolean)}.
-     */
-    @Deprecated
-    public DataMap loadEOModel(String path, boolean generateClientClass) throws Exception {
-        return loadEOModel(new File(path).toURI().toURL(), generateClientClass);
-    }
-
-    /**
-     * Performs EOModel loading.
-     * 
-     * @param url
-     *            URL of ".eomodeld" directory.
-     */
-    public DataMap loadEOModel(URL url) throws Exception {
-        return loadEOModel(url, false);
-    }
-
-    /**
-     * Performs EOModel loading.
-     * 
-     * @param url
-     *            URL of ".eomodeld" directory.
-     * @param generateClientClass
-     *            if true then loading of EOModel is java client classes aware
-     *            and the following processing will work with Java client class
-     *            settings of the EOModel.
-     */
-    public DataMap loadEOModel(URL url, boolean generateClientClass) throws Exception {
-        EOModelHelper helper = makeHelper(url);
-
-        // create empty map
-        DataMap dataMap = helper.getDataMap();
-
-        // process enitities ... throw out prototypes ... for now
-        List modelNames = new ArrayList(helper.modelNamesAsList());
-        CollectionUtils.filter(modelNames, PredicateUtils.notPredicate(prototypeChecker));
-
-        Iterator it = modelNames.iterator();
-        while (it.hasNext()) {
-            String name = (String) it.next();
-
-            // create and register entity
-            makeEntity(helper, name, generateClientClass);
-        }
-
-        // now sort following inheritance hierarchy
-        Collections.sort(modelNames, new InheritanceComparator(dataMap));
-
-        // after all entities are loaded, process attributes
-        it = modelNames.iterator();
-        while (it.hasNext()) {
-            String name = (String) it.next();
-
-            EOObjEntity e = (EOObjEntity) dataMap.getObjEntity(name);
-            // process entity attributes
-            makeAttributes(helper, e);
-        }
-
-        // after all entities are loaded, process relationships
-        it = modelNames.iterator();
-        while (it.hasNext()) {
-            String name = (String) it.next();
-            makeRelationships(helper, dataMap.getObjEntity(name));
-        }
-
-        // after all normal relationships are loaded, process flattened
-        // relationships
-        it = modelNames.iterator();
-        while (it.hasNext()) {
-            String name = (String) it.next();
-            makeFlatRelationships(helper, dataMap.getObjEntity(name));
-        }
-
-        // now create missing reverse DB (but not OBJ) relationships
-        // since Cayenne requires them
-        it = modelNames.iterator();
-        while (it.hasNext()) {
-            String name = (String) it.next();
-            DbEntity dbEntity = dataMap.getObjEntity(name).getDbEntity();
-
-            if (dbEntity != null) {
-                makeReverseDbRelationships(dbEntity);
-            }
-        }
-
-        // build SelectQueries out of EOFetchSpecifications...
-        it = modelNames.iterator();
-        while (it.hasNext()) {
-            String name = (String) it.next();
-            Iterator queries = helper.queryNames(name);
-            while (queries.hasNext()) {
-                String queryName = (String) queries.next();
-                EOObjEntity entity = (EOObjEntity) dataMap.getObjEntity(name);
-                makeQuery(helper, entity, queryName);
-            }
-        }
-
-        return dataMap;
-    }
-
-    /**
-     * Returns whether an Entity is an EOF EOPrototypes entity. According to EOF
-     * conventions EOPrototypes and EO[Adapter]Prototypes entities are
-     * considered to be prototypes.
-     * 
-     * @since 1.1
-     */
-    protected boolean isPrototypesEntity(String entityName) {
-        return prototypeChecker.evaluate(entityName);
-    }
-
-    /**
-     * Creates an returns new EOModelHelper to process EOModel. Exists mostly
-     * for the benefit of subclasses.
-     */
-    protected EOModelHelper makeHelper(URL url) throws Exception {
-        return new EOModelHelper(url);
-    }
-
-    /**
-     * Creates a Cayenne query out of EOFetchSpecification data.
-     * 
-     * @since 1.1
-     */
-    protected Query makeQuery(EOModelHelper helper, EOObjEntity entity, String queryName) {
-
-        DataMap dataMap = helper.getDataMap();
-        Map queryPlist = helper.queryPListMap(entity.getName(), queryName);
-        if (queryPlist == null) {
-            return null;
-        }
-
-        AbstractQuery query;
-        if (queryPlist.containsKey("hints")) { // just a predefined SQL query
-            query = new EOSQLQuery(entity, queryPlist);
-        } else {
-            query = new EOQuery(entity, queryPlist);
-        }
-        query.setName(entity.qualifiedQueryName(queryName));
-        dataMap.addQuery(query);
-
-        return query;
-    }
-
-    /**
-     * Creates and returns a new ObjEntity linked to a corresponding DbEntity.
-     */
-    protected EOObjEntity makeEntity(EOModelHelper helper, String name, boolean generateClientClass) {
-
-        DataMap dataMap = helper.getDataMap();
-        Map entityPlist = helper.entityPListMap(name);
-
-        // create ObjEntity
-        EOObjEntity objEntity = new EOObjEntity(name);
-        objEntity.setEoMap(entityPlist);
-        objEntity.setServerOnly(!generateClientClass);
-        String parent = (String) entityPlist.get("parent");
-        objEntity.setClassName(helper.entityClass(name, generateClientClass));
-
-        if (parent != null) {
-            objEntity.setSubclass(true);
-            objEntity.setSuperClassName(helper.entityClass(parent, generateClientClass));
-        }
-
-        // add flag whether this entity is set as abstract in the model
-        objEntity.setAbstractEntity("Y".equals(entityPlist.get("isAbstractEntity")));
-
-        // create DbEntity...since EOF allows the same table to be
-        // associated with multiple EOEntities, check for name duplicates
-        String dbEntityName = (String) entityPlist.get("externalName");
-        if (dbEntityName != null) {
-
-            // ... if inheritance is involved and parent hierarchy uses the same
-            // DBEntity,
-            // do not create a DbEntity...
-            boolean createDbEntity = true;
-            if (parent != null) {
-                String parentName = parent;
-                while (parentName != null) {
-                    Map parentData = helper.entityPListMap(parentName);
-                    if (parentData == null) {
-                        break;
-                    }
-
-                    String parentExternalName = (String) parentData.get("externalName");
-                    if (parentExternalName == null) {
-                        parentName = (String) parentData.get("parent");
-                        continue;
-                    }
-
-                    if (dbEntityName.equals(parentExternalName)) {
-                        createDbEntity = false;
-                    }
-
-                    break;
-                }
-            }
-
-            if (createDbEntity) {
-                int i = 0;
-                String dbEntityBaseName = dbEntityName;
-                while (dataMap.getDbEntity(dbEntityName) != null) {
-                    dbEntityName = dbEntityBaseName + i++;
-                }
-
-                objEntity.setDbEntityName(dbEntityName);
-                DbEntity de = new DbEntity(dbEntityName);
-                dataMap.addDbEntity(de);
-            }
-        }
-
-        // set various flags
-        objEntity.setReadOnly("Y".equals(entityPlist.get("isReadOnly")));
-        objEntity.setSuperEntityName((String) entityPlist.get("parent"));
-
-        dataMap.addObjEntity(objEntity);
-
-        return objEntity;
-    }
-
-    /**
-     * Create ObjAttributes of the specified entity, as well as DbAttributes of
-     * the corresponding DbEntity.
-     */
-    protected void makeAttributes(EOModelHelper helper, EOObjEntity objEntity) {
-        Map entityPlistMap = helper.entityPListMap(objEntity.getName());
-        List primaryKeys = (List) entityPlistMap.get("primaryKeyAttributes");
-
-        List classProperties;
-        if (objEntity.isServerOnly()) {
-            classProperties = (List) entityPlistMap.get("classProperties");
-        } else {
-            classProperties = (List) entityPlistMap.get("clientClassProperties");
-        }
-
-        List attributes = (List) entityPlistMap.get("attributes");
-        DbEntity dbEntity = objEntity.getDbEntity();
-
-        if (primaryKeys == null) {
-            primaryKeys = Collections.EMPTY_LIST;
-        }
-
-        if (classProperties == null) {
-            classProperties = Collections.EMPTY_LIST;
-        }
-
-        if (attributes == null) {
-            attributes = Collections.EMPTY_LIST;
-        }
-
-        // detect single table inheritance
-        boolean singleTableInheritance = false;
-        String parentName = (String) entityPlistMap.get("parent");
-        while (parentName != null) {
-            Map parentData = helper.entityPListMap(parentName);
-            if (parentData == null) {
-                break;
-            }
-
-            String parentExternalName = (String) parentData.get("externalName");
-            if (parentExternalName == null) {
-                parentName = (String) parentData.get("parent");
-                continue;
-            }
-
-            if (dbEntity.getName() != null && dbEntity.getName().equals(parentExternalName)) {
-                singleTableInheritance = true;
-            }
-
-            break;
-        }
-
-        Iterator it = attributes.iterator();
-        while (it.hasNext()) {
-            Map attrMap = (Map) it.next();
-
-            String prototypeName = (String) attrMap.get("prototypeName");
-            Map prototypeAttrMap = helper.getPrototypeAttributeMapFor(prototypeName);
-
-            String dbAttrName = (String) attrMap.get("columnName");
-            if (null == dbAttrName) {
-                dbAttrName = (String) prototypeAttrMap.get("columnName");
-            }
-
-            String attrName = (String) attrMap.get("name");
-            if (null == attrName) {
-                attrName = (String) prototypeAttrMap.get("name");
-            }
-
-            String attrType = (String) attrMap.get("valueClassName");
-            if (null == attrType) {
-                attrType = (String) prototypeAttrMap.get("valueClassName");
-            }
-
-            String valueType = (String) attrMap.get("valueType");
-            if (valueType == null) {
-                valueType = (String) prototypeAttrMap.get("valueType");
-            }
-
-            String javaType = helper.javaTypeForEOModelerType(attrType, valueType);
-            EODbAttribute dbAttr = null;
-
-            if (dbAttrName != null && dbEntity != null) {
-
-                // if inherited attribute, skip it for DbEntity...
-                if (!singleTableInheritance || dbEntity.getAttribute(dbAttrName) == null) {
-
-                    // create DbAttribute...since EOF allows the same column
-                    // name for
-                    // more than one Java attribute, we need to check for name
-                    // duplicates
-                    int i = 0;
-                    String dbAttributeBaseName = dbAttrName;
-                    while (dbEntity.getAttribute(dbAttrName) != null) {
-                        dbAttrName = dbAttributeBaseName + i++;
-                    }
-
-                    dbAttr = new EODbAttribute(dbAttrName, TypesMapping.getSqlTypeByJava(javaType), dbEntity);
-                    dbAttr.setEoAttributeName(attrName);
-                    dbEntity.addAttribute(dbAttr);
-
-                    int width = getInt("width", attrMap, prototypeAttrMap, -1);
-                    if (width >= 0) {
-                        dbAttr.setMaxLength(width);
-                    }
-
-                    int scale = getInt("scale", attrMap, prototypeAttrMap, -1);
-                    if (scale >= 0) {
-                        dbAttr.setScale(scale);
-                    }
-
-                    if (primaryKeys.contains(attrName))
-                        dbAttr.setPrimaryKey(true);
-
-                    Object allowsNull = attrMap.get("allowsNull");
-                    // TODO: Unclear that allowsNull should be inherited from
-                    // EOPrototypes
-                    // if (null == allowsNull) allowsNull =
-                    // prototypeAttrMap.get("allowsNull");;
-
-                    dbAttr.setMandatory(!"Y".equals(allowsNull));
-                }
-            }
-
-            if (classProperties.contains(attrName)) {
-                EOObjAttribute attr = new EOObjAttribute(attrName, javaType, objEntity);
-
-                // set readOnly flag of Attribute if either attribute is read or
-                // if entity is readOnly
-                String entityReadOnlyString = (String) entityPlistMap.get("isReadOnly");
-                String attributeReadOnlyString = (String) attrMap.get("isReadOnly");
-                if ("Y".equals(entityReadOnlyString) || "Y".equals(attributeReadOnlyString)) {
-                    attr.setReadOnly(true);
-                }
-
-                // set name instead of the actual attribute, as it may be
-                // inherited....
-                attr.setDbAttributePath(dbAttrName);
-                objEntity.addAttribute(attr);
-            }
-        }
-    }
-
-    int getInt(String key, Map map, Map prototypes, int defaultValue) {
-
-        Object value = map.get(key);
-        if (value == null) {
-            value = prototypes.get(key);
-        }
-
-        if (value == null) {
-            return defaultValue;
-        }
-
-        // per CAY-752, value can be a String or a Number, so handle both
-        if (value instanceof Number) {
-            return ((Number) value).intValue();
-        } else {
-            try {
-                return Integer.parseInt(value.toString());
-            } catch (NumberFormatException nfex) {
-                return defaultValue;
-            }
-        }
-    }
-
-    /**
-     * Create ObjRelationships of the specified entity, as well as
-     * DbRelationships of the corresponding DbEntity.
-     */
-    protected void makeRelationships(EOModelHelper helper, ObjEntity objEntity) {
-        Map entityPlistMap = helper.entityPListMap(objEntity.getName());
-        List classProps = (List) entityPlistMap.get("classProperties");
-        List rinfo = (List) entityPlistMap.get("relationships");
-
-        Collection attributes = (Collection) entityPlistMap.get("attributes");
-
-        if (rinfo == null) {
-            return;
-        }
-
-        if (classProps == null) {
-            classProps = Collections.EMPTY_LIST;
-        }
-
-        if (attributes == null) {
-            attributes = Collections.EMPTY_LIST;
-        }
-
-        DbEntity dbSrc = objEntity.getDbEntity();
-        Iterator it = rinfo.iterator();
-        while (it.hasNext()) {
-            Map relMap = (Map) it.next();
-            String targetName = (String) relMap.get("destination");
-
-            // ignore flattened relationships for now
-            if (targetName == null) {
-                continue;
-            }
-
-            String relName = (String) relMap.get("name");
-            boolean toMany = "Y".equals(relMap.get("isToMany"));
-            boolean toDependentPK = "Y".equals(relMap.get("propagatesPrimaryKey"));
-            ObjEntity target = helper.getDataMap().getObjEntity(targetName);
-
-            // target maybe null for cross-EOModel relationships
-            // ignoring those now.
-            if (target == null) {
-                continue;
-            }
-
-            DbEntity dbTarget = target.getDbEntity();
-            Map targetPlistMap = helper.entityPListMap(targetName);
-            Collection targetAttributes = (Collection) targetPlistMap.get("attributes");
-            DbRelationship dbRel = null;
-
-            // process underlying DbRelationship
-            // Note: there is no flattened rel. support here....
-            // Note: source maybe null, e.g. an abstract entity.
-            if (dbSrc != null && dbTarget != null) {
-
-                // in case of inheritance EOF stores duplicates of all inherited
-                // relationships, so we must skip this relationship in DB entity
-                // if it is
-                // already there...
-
-                dbRel = dbSrc.getRelationship(relName);
-                if (dbRel == null) {
-
-                    dbRel = new DbRelationship();
-                    dbRel.setSourceEntity(dbSrc);
-                    dbRel.setTargetEntityName(dbTarget);
-                    dbRel.setToMany(toMany);
-                    dbRel.setName(relName);
-                    dbRel.setToDependentPK(toDependentPK);
-                    dbSrc.addRelationship(dbRel);
-
-                    List joins = (List) relMap.get("joins");
-                    Iterator jIt = joins.iterator();
-                    while (jIt.hasNext()) {
-                        Map joinMap = (Map) jIt.next();
-
-                        DbJoin join = new DbJoin(dbRel);
-
-                        // find source attribute dictionary and extract the
-                        // column name
-                        String sourceAttributeName = (String) joinMap.get("sourceAttribute");
-                        join.setSourceName(columnName(attributes, sourceAttributeName));
-
-                        String targetAttributeName = (String) joinMap.get("destinationAttribute");
-
-                        join.setTargetName(columnName(targetAttributes, targetAttributeName));
-                        dbRel.addJoin(join);
-                    }
-                }
-            }
-
-            // only create obj relationship if it is a class property
-            if (classProps.contains(relName)) {
-                ObjRelationship rel = new ObjRelationship();
-                rel.setName(relName);
-                rel.setSourceEntity(objEntity);
-                rel.setTargetEntityName(target);
-                objEntity.addRelationship(rel);
-
-                if (dbRel != null) {
-                    rel.addDbRelationship(dbRel);
-                }
-            }
-        }
-    }
-
-    /**
-     * Create reverse DbRelationships that were not created so far, since
-     * Cayenne requires them.
-     * 
-     * @since 1.0.5
-     */
-    protected void makeReverseDbRelationships(DbEntity dbEntity) {
-        if (dbEntity == null) {
-            throw new NullPointerException("Attempt to create reverse relationships for the null DbEntity.");
-        }
-
-        // iterate over a copy of the collection, since in case of
-        // reflexive relationships, we may modify source entity relationship map
-
-        for (DbRelationship relationship : new ArrayList<DbRelationship>(dbEntity.getRelationships())) {
-
-            if (relationship.getReverseRelationship() == null) {
-                DbRelationship reverse = relationship.createReverseRelationship();
-
-                String name = DefaultUniqueNameGenerator.generate(NameCheckers.dbRelationship, reverse.getSourceEntity(), relationship.getName() + "Reverse");
-                reverse.setName(name);
-                relationship.getTargetEntity().addRelationship(reverse);
-            }
-        }
-    }
-
-    /**
-     * Create Flattened ObjRelationships of the specified entity.
-     */
-    protected void makeFlatRelationships(EOModelHelper helper, ObjEntity e) {
-        Map info = helper.entityPListMap(e.getName());
-        List rinfo = (List) info.get("relationships");
-        if (rinfo == null) {
-            return;
-        }
-
-        Iterator it = rinfo.iterator();
-        while (it.hasNext()) {
-            Map relMap = (Map) it.next();
-            String targetPath = (String) relMap.get("definition");
-
-            // ignore normal relationships
-            if (targetPath == null) {
-                continue;
-            }
-
-            ObjRelationship flatRel = new ObjRelationship();
-            flatRel.setName((String) relMap.get("name"));
-            flatRel.setSourceEntity(e);
-
-            try {
-                flatRel.setDbRelationshipPath(targetPath);
-            } catch (ExpressionException ex) {
-                logger.warn("Invalid relationship: " + targetPath);
-                continue;
-            }
-
-            // find target entity
-            Map entityInfo = info;
-            StringTokenizer toks = new StringTokenizer(targetPath, ".");
-            while (toks.hasMoreTokens() && entityInfo != null) {
-                String pathComponent = toks.nextToken();
-
-                // get relationship info and reset entityInfo, so that we could
-                // use
-                // entityInfo state as an indicator of valid flat relationship
-                // enpoint
-                // outside the loop
-                Collection relationshipInfo = (Collection) entityInfo.get("relationships");
-                entityInfo = null;
-
-                if (relationshipInfo == null) {
-                    break;
-                }
-
-                Iterator rit = relationshipInfo.iterator();
-                while (rit.hasNext()) {
-                    Map pathRelationship = (Map) rit.next();
-                    if (pathComponent.equals(pathRelationship.get("name"))) {
-                        String targetName = (String) pathRelationship.get("destination");
-                        entityInfo = helper.entityPListMap(targetName);
-                        break;
-                    }
-                }
-            }
-
-            if (entityInfo != null) {
-                flatRel.setTargetEntityName((String) entityInfo.get("name"));
-            }
-
-            e.addRelationship(flatRel);
-        }
-    }
-
-    /**
-     * Locates an attribute map matching the name and returns column name for
-     * this attribute.
-     * 
-     * @since 1.1
-     */
-    String columnName(Collection entityAttributes, String attributeName) {
-        if (attributeName == null) {
-            return null;
-        }
-
-        Iterator it = entityAttributes.iterator();
-        while (it.hasNext()) {
-            Map map = (Map) it.next();
-            if (attributeName.equals(map.get("name"))) {
-                return (String) map.get("columnName");
-            }
-        }
-
-        return null;
-    }
-
-    // sorts ObjEntities so that subentities in inheritance hierarchy are shown
-    // last
-    final class InheritanceComparator implements Comparator {
-
-        DataMap dataMap;
-
-        InheritanceComparator(DataMap dataMap) {
-            this.dataMap = dataMap;
-        }
-
-        public int compare(Object o1, Object o2) {
-            if (o1 == null) {
-                return o2 != null ? -1 : 0;
-            } else if (o2 == null) {
-                return 1;
-            }
-
-            String name1 = o1.toString();
-            String name2 = o2.toString();
-
-            ObjEntity e1 = dataMap.getObjEntity(name1);
-            ObjEntity e2 = dataMap.getObjEntity(name2);
-
-            return compareEntities(e1, e2);
-        }
-
-        int compareEntities(ObjEntity e1, ObjEntity e2) {
-            if (e1 == null) {
-                return e2 != null ? -1 : 0;
-            } else if (e2 == null) {
-                return 1;
-            }
-
-            // entity goes first if it is a direct or indirect superentity of
-            // another
-            // one
-            if (e1.isSubentityOf(e2)) {
-                return 1;
-            }
-
-            if (e2.isSubentityOf(e1)) {
-                return -1;
-            }
-
-            // sort alphabetically
-            return e1.getName().compareTo(e2.getName());
-        }
-    }
+	private static final Log logger = LogFactory.getLog(EOModelProcessor.class);
+
+	protected Predicate prototypeChecker;
+
+	public EOModelProcessor() {
+		prototypeChecker = new Predicate() {
+
+			public boolean evaluate(Object object) {
+				if (object == null) {
+					return false;
+				}
+
+				String entityName = object.toString();
+				return entityName.startsWith("EO") && entityName.endsWith("Prototypes");
+			}
+		};
+	}
+
+	/**
+	 * @deprecated since 4.0 in favor of {@link #loadModeIndex(URL)}.
+	 */
+	@Deprecated
+	public Map loadModeIndex(String path) throws Exception {
+		return loadModeIndex(new File(path).toURI().toURL());
+	}
+
+	/**
+	 * Returns index.eomodeld contents as a Map.
+	 * 
+	 * @since 4.0
+	 */
+	// TODO: refactor EOModelHelper to provide a similar method without loading
+	// all entity files in memory... here we simply copied stuff from
+	// EOModelHelper
+	public Map loadModeIndex(URL url) throws Exception {
+
+		String urlString = url.toExternalForm();
+
+		if (!urlString.endsWith(".eomodeld")) {
+			url = new URL(urlString + ".eomodeld");
+		}
+
+		Parser plistParser = new Parser();
+
+		try (InputStream in = new URL(url, "index.eomodeld").openStream();) {
+			plistParser.ReInit(in);
+			return (Map) plistParser.propertyList();
+		}
+	}
+
+	/**
+	 * @deprecated since 4.0 in favor of {@link #loadEOModel(URL)}.
+	 */
+	@Deprecated
+	public DataMap loadEOModel(String path) throws Exception {
+		return loadEOModel(path, false);
+	}
+
+	/**
+	 * @deprecated since 4.0 in favor of {@link #loadEOModel(URL, boolean)}.
+	 */
+	@Deprecated
+	public DataMap loadEOModel(String path, boolean generateClientClass) throws Exception {
+		return loadEOModel(new File(path).toURI().toURL(), generateClientClass);
+	}
+
+	/**
+	 * Performs EOModel loading.
+	 * 
+	 * @param url
+	 *            URL of ".eomodeld" directory.
+	 */
+	public DataMap loadEOModel(URL url) throws Exception {
+		return loadEOModel(url, false);
+	}
+
+	/**
+	 * Performs EOModel loading.
+	 * 
+	 * @param url
+	 *            URL of ".eomodeld" directory.
+	 * @param generateClientClass
+	 *            if true then loading of EOModel is java client classes aware
+	 *            and the following processing will work with Java client class
+	 *            settings of the EOModel.
+	 */
+	public DataMap loadEOModel(URL url, boolean generateClientClass) throws Exception {
+		EOModelHelper helper = makeHelper(url);
+
+		// create empty map
+		DataMap dataMap = helper.getDataMap();
+
+		// process enitities ... throw out prototypes ... for now
+		List modelNames = new ArrayList(helper.modelNamesAsList());
+		CollectionUtils.filter(modelNames, PredicateUtils.notPredicate(prototypeChecker));
+
+		Iterator it = modelNames.iterator();
+		while (it.hasNext()) {
+			String name = (String) it.next();
+
+			// create and register entity
+			makeEntity(helper, name, generateClientClass);
+		}
+
+		// now sort following inheritance hierarchy
+		Collections.sort(modelNames, new InheritanceComparator(dataMap));
+
+		// after all entities are loaded, process attributes
+		it = modelNames.iterator();
+		while (it.hasNext()) {
+			String name = (String) it.next();
+
+			EOObjEntity e = (EOObjEntity) dataMap.getObjEntity(name);
+			// process entity attributes
+			makeAttributes(helper, e);
+		}
+
+		// after all entities are loaded, process relationships
+		it = modelNames.iterator();
+		while (it.hasNext()) {
+			String name = (String) it.next();
+			makeRelationships(helper, dataMap.getObjEntity(name));
+		}
+
+		// after all normal relationships are loaded, process flattened
+		// relationships
+		it = modelNames.iterator();
+		while (it.hasNext()) {
+			String name = (String) it.next();
+			makeFlatRelationships(helper, dataMap.getObjEntity(name));
+		}
+
+		// now create missing reverse DB (but not OBJ) relationships
+		// since Cayenne requires them
+		it = modelNames.iterator();
+		while (it.hasNext()) {
+			String name = (String) it.next();
+			DbEntity dbEntity = dataMap.getObjEntity(name).getDbEntity();
+
+			if (dbEntity != null) {
+				makeReverseDbRelationships(dbEntity);
+			}
+		}
+
+		// build SelectQueries out of EOFetchSpecifications...
+		it = modelNames.iterator();
+		while (it.hasNext()) {
+			String name = (String) it.next();
+			Iterator queries = helper.queryNames(name);
+			while (queries.hasNext()) {
+				String queryName = (String) queries.next();
+				EOObjEntity entity = (EOObjEntity) dataMap.getObjEntity(name);
+				makeQuery(helper, entity, queryName);
+			}
+		}
+
+		return dataMap;
+	}
+
+	/**
+	 * Returns whether an Entity is an EOF EOPrototypes entity. According to EOF
+	 * conventions EOPrototypes and EO[Adapter]Prototypes entities are
+	 * considered to be prototypes.
+	 * 
+	 * @since 1.1
+	 */
+	protected boolean isPrototypesEntity(String entityName) {
+		return prototypeChecker.evaluate(entityName);
+	}
+
+	/**
+	 * Creates an returns new EOModelHelper to process EOModel. Exists mostly
+	 * for the benefit of subclasses.
+	 */
+	protected EOModelHelper makeHelper(URL url) throws Exception {
+		return new EOModelHelper(url);
+	}
+
+	/**
+	 * Creates a Cayenne query out of EOFetchSpecification data.
+	 * 
+	 * @since 1.1
+	 */
+	protected Query makeQuery(EOModelHelper helper, EOObjEntity entity, String queryName) {
+
+		DataMap dataMap = helper.getDataMap();
+		Map queryPlist = helper.queryPListMap(entity.getName(), queryName);
+		if (queryPlist == null) {
+			return null;
+		}
+
+		AbstractQuery query;
+		if (queryPlist.containsKey("hints")) { // just a predefined SQL query
+			query = new EOSQLQuery(entity, queryPlist);
+		} else {
+			query = new EOQuery(entity, queryPlist);
+		}
+		query.setName(entity.qualifiedQueryName(queryName));
+		dataMap.addQuery(query);
+
+		return query;
+	}
+
+	/**
+	 * Creates and returns a new ObjEntity linked to a corresponding DbEntity.
+	 */
+	protected EOObjEntity makeEntity(EOModelHelper helper, String name, boolean generateClientClass) {
+
+		DataMap dataMap = helper.getDataMap();
+		Map entityPlist = helper.entityPListMap(name);
+
+		// create ObjEntity
+		EOObjEntity objEntity = new EOObjEntity(name);
+		objEntity.setEoMap(entityPlist);
+		objEntity.setServerOnly(!generateClientClass);
+		String parent = (String) entityPlist.get("parent");
+		objEntity.setClassName(helper.entityClass(name, generateClientClass));
+
+		if (parent != null) {
+			objEntity.setSubclass(true);
+			objEntity.setSuperClassName(helper.entityClass(parent, generateClientClass));
+		}
+
+		// add flag whether this entity is set as abstract in the model
+		objEntity.setAbstractEntity("Y".equals(entityPlist.get("isAbstractEntity")));
+
+		// create DbEntity...since EOF allows the same table to be
+		// associated with multiple EOEntities, check for name duplicates
+		String dbEntityName = (String) entityPlist.get("externalName");
+		if (dbEntityName != null) {
+
+			// ... if inheritance is involved and parent hierarchy uses the same
+			// DBEntity,
+			// do not create a DbEntity...
+			boolean createDbEntity = true;
+			if (parent != null) {
+				String parentName = parent;
+				while (parentName != null) {
+					Map parentData = helper.entityPListMap(parentName);
+					if (parentData == null) {
+						break;
+					}
+
+					String parentExternalName = (String) parentData.get("externalName");
+					if (parentExternalName == null) {
+						parentName = (String) parentData.get("parent");
+						continue;
+					}
+
+					if (dbEntityName.equals(parentExternalName)) {
+						createDbEntity = false;
+					}
+
+					break;
+				}
+			}
+
+			if (createDbEntity) {
+				int i = 0;
+				String dbEntityBaseName = dbEntityName;
+				while (dataMap.getDbEntity(dbEntityName) != null) {
+					dbEntityName = dbEntityBaseName + i++;
+				}
+
+				objEntity.setDbEntityName(dbEntityName);
+				DbEntity de = new DbEntity(dbEntityName);
+				dataMap.addDbEntity(de);
+			}
+		}
+
+		// set various flags
+		objEntity.setReadOnly("Y".equals(entityPlist.get("isReadOnly")));
+		objEntity.setSuperEntityName((String) entityPlist.get("parent"));
+
+		dataMap.addObjEntity(objEntity);
+
+		return objEntity;
+	}
+
+	/**
+	 * Create ObjAttributes of the specified entity, as well as DbAttributes of
+	 * the corresponding DbEntity.
+	 */
+	protected void makeAttributes(EOModelHelper helper, EOObjEntity objEntity) {
+		Map entityPlistMap = helper.entityPListMap(objEntity.getName());
+		List primaryKeys = (List) entityPlistMap.get("primaryKeyAttributes");
+
+		List classProperties;
+		if (objEntity.isServerOnly()) {
+			classProperties = (List) entityPlistMap.get("classProperties");
+		} else {
+			classProperties = (List) entityPlistMap.get("clientClassProperties");
+		}
+
+		List attributes = (List) entityPlistMap.get("attributes");
+		DbEntity dbEntity = objEntity.getDbEntity();
+
+		if (primaryKeys == null) {
+			primaryKeys = Collections.EMPTY_LIST;
+		}
+
+		if (classProperties == null) {
+			classProperties = Collections.EMPTY_LIST;
+		}
+
+		if (attributes == null) {
+			attributes = Collections.EMPTY_LIST;
+		}
+
+		// detect single table inheritance
+		boolean singleTableInheritance = false;
+		String parentName = (String) entityPlistMap.get("parent");
+		while (parentName != null) {
+			Map parentData = helper.entityPListMap(parentName);
+			if (parentData == null) {
+				break;
+			}
+
+			String parentExternalName = (String) parentData.get("externalName");
+			if (parentExternalName == null) {
+				parentName = (String) parentData.get("parent");
+				continue;
+			}
+
+			if (dbEntity.getName() != null && dbEntity.getName().equals(parentExternalName)) {
+				singleTableInheritance = true;
+			}
+
+			break;
+		}
+
+		Iterator it = attributes.iterator();
+		while (it.hasNext()) {
+			Map attrMap = (Map) it.next();
+
+			String prototypeName = (String) attrMap.get("prototypeName");
+			Map prototypeAttrMap = helper.getPrototypeAttributeMapFor(prototypeName);
+
+			String dbAttrName = (String) attrMap.get("columnName");
+			if (null == dbAttrName) {
+				dbAttrName = (String) prototypeAttrMap.get("columnName");
+			}
+
+			String attrName = (String) attrMap.get("name");
+			if (null == attrName) {
+				attrName = (String) prototypeAttrMap.get("name");
+			}
+
+			String attrType = (String) attrMap.get("valueClassName");
+			if (null == attrType) {
+				attrType = (String) prototypeAttrMap.get("valueClassName");
+			}
+
+			String valueType = (String) attrMap.get("valueType");
+			if (valueType == null) {
+				valueType = (String) prototypeAttrMap.get("valueType");
+			}
+
+			String javaType = helper.javaTypeForEOModelerType(attrType, valueType);
+			EODbAttribute dbAttr = null;
+
+			if (dbAttrName != null && dbEntity != null) {
+
+				// if inherited attribute, skip it for DbEntity...
+				if (!singleTableInheritance || dbEntity.getAttribute(dbAttrName) == null) {
+
+					// create DbAttribute...since EOF allows the same column
+					// name for
+					// more than one Java attribute, we need to check for name
+					// duplicates
+					int i = 0;
+					String dbAttributeBaseName = dbAttrName;
+					while (dbEntity.getAttribute(dbAttrName) != null) {
+						dbAttrName = dbAttributeBaseName + i++;
+					}
+
+					dbAttr = new EODbAttribute(dbAttrName, TypesMapping.getSqlTypeByJava(javaType), dbEntity);
+					dbAttr.setEoAttributeName(attrName);
+					dbEntity.addAttribute(dbAttr);
+
+					int width = getInt("width", attrMap, prototypeAttrMap, -1);
+					if (width >= 0) {
+						dbAttr.setMaxLength(width);
+					}
+
+					int scale = getInt("scale", attrMap, prototypeAttrMap, -1);
+					if (scale >= 0) {
+						dbAttr.setScale(scale);
+					}
+
+					if (primaryKeys.contains(attrName))
+						dbAttr.setPrimaryKey(true);
+
+					Object allowsNull = attrMap.get("allowsNull");
+					// TODO: Unclear that allowsNull should be inherited from
+					// EOPrototypes
+					// if (null == allowsNull) allowsNull =
+					// prototypeAttrMap.get("allowsNull");;
+
+					dbAttr.setMandatory(!"Y".equals(allowsNull));
+				}
+			}
+
+			if (classProperties.contains(attrName)) {
+				EOObjAttribute attr = new EOObjAttribute(attrName, javaType, objEntity);
+
+				// set readOnly flag of Attribute if either attribute is read or
+				// if entity is readOnly
+				String entityReadOnlyString = (String) entityPlistMap.get("isReadOnly");
+				String attributeReadOnlyString = (String) attrMap.get("isReadOnly");
+				if ("Y".equals(entityReadOnlyString) || "Y".equals(attributeReadOnlyString)) {
+					attr.setReadOnly(true);
+				}
+
+				// set name instead of the actual attribute, as it may be
+				// inherited....
+				attr.setDbAttributePath(dbAttrName);
+				objEntity.addAttribute(attr);
+			}
+		}
+	}
+
+	int getInt(String key, Map map, Map prototypes, int defaultValue) {
+
+		Object value = map.get(key);
+		if (value == null) {
+			value = prototypes.get(key);
+		}
+
+		if (value == null) {
+			return defaultValue;
+		}
+
+		// per CAY-752, value can be a String or a Number, so handle both
+		if (value instanceof Number) {
+			return ((Number) value).intValue();
+		} else {
+			try {
+				return Integer.parseInt(value.toString());
+			} catch (NumberFormatException nfex) {
+				return defaultValue;
+			}
+		}
+	}
+
+	/**
+	 * Create ObjRelationships of the specified entity, as well as
+	 * DbRelationships of the corresponding DbEntity.
+	 */
+	protected void makeRelationships(EOModelHelper helper, ObjEntity objEntity) {
+		Map entityPlistMap = helper.entityPListMap(objEntity.getName());
+		List classProps = (List) entityPlistMap.get("classProperties");
+		List rinfo = (List) entityPlistMap.get("relationships");
+
+		Collection attributes = (Collection) entityPlistMap.get("attributes");
+
+		if (rinfo == null) {
+			return;
+		}
+
+		if (classProps == null) {
+			classProps = Collections.EMPTY_LIST;
+		}
+
+		if (attributes == null) {
+			attributes = Collections.EMPTY_LIST;
+		}
+
+		DbEntity dbSrc = objEntity.getDbEntity();
+		Iterator it = rinfo.iterator();
+		while (it.hasNext()) {
+			Map relMap = (Map) it.next();
+			String targetName = (String) relMap.get("destination");
+
+			// ignore flattened relationships for now
+			if (targetName == null) {
+				continue;
+			}
+
+			String relName = (String) relMap.get("name");
+			boolean toMany = "Y".equals(relMap.get("isToMany"));
+			boolean toDependentPK = "Y".equals(relMap.get("propagatesPrimaryKey"));
+			ObjEntity target = helper.getDataMap().getObjEntity(targetName);
+
+			// target maybe null for cross-EOModel relationships
+			// ignoring those now.
+			if (target == null) {
+				continue;
+			}
+
+			DbEntity dbTarget = target.getDbEntity();
+			Map targetPlistMap = helper.entityPListMap(targetName);
+			Collection targetAttributes = (Collection) targetPlistMap.get("attributes");
+			DbRelationship dbRel = null;
+
+			// process underlying DbRelationship
+			// Note: there is no flattened rel. support here....
+			// Note: source maybe null, e.g. an abstract entity.
+			if (dbSrc != null && dbTarget != null) {
+
+				// in case of inheritance EOF stores duplicates of all inherited
+				// relationships, so we must skip this relationship in DB entity
+				// if it is
+				// already there...
+
+				dbRel = dbSrc.getRelationship(relName);
+				if (dbRel == null) {
+
+					dbRel = new DbRelationship();
+					dbRel.setSourceEntity(dbSrc);
+					dbRel.setTargetEntityName(dbTarget);
+					dbRel.setToMany(toMany);
+					dbRel.setName(relName);
+					dbRel.setToDependentPK(toDependentPK);
+					dbSrc.addRelationship(dbRel);
+
+					List joins = (List) relMap.get("joins");
+					Iterator jIt = joins.iterator();
+					while (jIt.hasNext()) {
+						Map joinMap = (Map) jIt.next();
+
+						DbJoin join = new DbJoin(dbRel);
+
+						// find source attribute dictionary and extract the
+						// column name
+						String sourceAttributeName = (String) joinMap.get("sourceAttribute");
+						join.setSourceName(columnName(attributes, sourceAttributeName));
+
+						String targetAttributeName = (String) joinMap.get("destinationAttribute");
+
+						join.setTargetName(columnName(targetAttributes, targetAttributeName));
+						dbRel.addJoin(join);
+					}
+				}
+			}
+
+			// only create obj relationship if it is a class property
+			if (classProps.contains(relName)) {
+				ObjRelationship rel = new ObjRelationship();
+				rel.setName(relName);
+				rel.setSourceEntity(objEntity);
+				rel.setTargetEntityName(target);
+				objEntity.addRelationship(rel);
+
+				if (dbRel != null) {
+					rel.addDbRelationship(dbRel);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Create reverse DbRelationships that were not created so far, since
+	 * Cayenne requires them.
+	 * 
+	 * @since 1.0.5
+	 */
+	protected void makeReverseDbRelationships(DbEntity dbEntity) {
+		if (dbEntity == null) {
+			throw new NullPointerException("Attempt to create reverse relationships for the null DbEntity.");
+		}
+
+		// iterate over a copy of the collection, since in case of
+		// reflexive relationships, we may modify source entity relationship map
+
+		for (DbRelationship relationship : new ArrayList<DbRelationship>(dbEntity.getRelationships())) {
+
+			if (relationship.getReverseRelationship() == null) {
+				DbRelationship reverse = relationship.createReverseRelationship();
+
+				String name = DefaultUniqueNameGenerator.generate(NameCheckers.dbRelationship,
+						reverse.getSourceEntity(), relationship.getName() + "Reverse");
+				reverse.setName(name);
+				relationship.getTargetEntity().addRelationship(reverse);
+			}
+		}
+	}
+
+	/**
+	 * Create Flattened ObjRelationships of the specified entity.
+	 */
+	protected void makeFlatRelationships(EOModelHelper helper, ObjEntity e) {
+		Map info = helper.entityPListMap(e.getName());
+		List rinfo = (List) info.get("relationships");
+		if (rinfo == null) {
+			return;
+		}
+
+		Iterator it = rinfo.iterator();
+		while (it.hasNext()) {
+			Map relMap = (Map) it.next();
+			String targetPath = (String) relMap.get("definition");
+
+			// ignore normal relationships
+			if (targetPath == null) {
+				continue;
+			}
+
+			ObjRelationship flatRel = new ObjRelationship();
+			flatRel.setName((String) relMap.get("name"));
+			flatRel.setSourceEntity(e);
+
+			try {
+				flatRel.setDbRelationshipPath(targetPath);
+			} catch (ExpressionException ex) {
+				logger.warn("Invalid relationship: " + targetPath);
+				continue;
+			}
+
+			// find target entity
+			Map entityInfo = info;
+			StringTokenizer toks = new StringTokenizer(targetPath, ".");
+			while (toks.hasMoreTokens() && entityInfo != null) {
+				String pathComponent = toks.nextToken();
+
+				// get relationship info and reset entityInfo, so that we could
+				// use
+				// entityInfo state as an indicator of valid flat relationship
+				// enpoint
+				// outside the loop
+				Collection relationshipInfo = (Collection) entityInfo.get("relationships");
+				entityInfo = null;
+
+				if (relationshipInfo == null) {
+					break;
+				}
+
+				Iterator rit = relationshipInfo.iterator();
+				while (rit.hasNext()) {
+					Map pathRelationship = (Map) rit.next();
+					if (pathComponent.equals(pathRelationship.get("name"))) {
+						String targetName = (String) pathRelationship.get("destination");
+						entityInfo = helper.entityPListMap(targetName);
+						break;
+					}
+				}
+			}
+
+			if (entityInfo != null) {
+				flatRel.setTargetEntityName((String) entityInfo.get("name"));
+			}
+
+			e.addRelationship(flatRel);
+		}
+	}
+
+	/**
+	 * Locates an attribute map matching the name and returns column name for
+	 * this attribute.
+	 * 
+	 * @since 1.1
+	 */
+	String columnName(Collection entityAttributes, String attributeName) {
+		if (attributeName == null) {
+			return null;
+		}
+
+		Iterator it = entityAttributes.iterator();
+		while (it.hasNext()) {
+			Map map = (Map) it.next();
+			if (attributeName.equals(map.get("name"))) {
+				return (String) map.get("columnName");
+			}
+		}
+
+		return null;
+	}
+
+	// sorts ObjEntities so that subentities in inheritance hierarchy are shown
+	// last
+	final class InheritanceComparator implements Comparator {
+
+		DataMap dataMap;
+
+		InheritanceComparator(DataMap dataMap) {
+			this.dataMap = dataMap;
+		}
+
+		public int compare(Object o1, Object o2) {
+			if (o1 == null) {
+				return o2 != null ? -1 : 0;
+			} else if (o2 == null) {
+				return 1;
+			}
+
+			String name1 = o1.toString();
+			String name2 = o2.toString();
+
+			ObjEntity e1 = dataMap.getObjEntity(name1);
+			ObjEntity e2 = dataMap.getObjEntity(name2);
+
+			return compareEntities(e1, e2);
+		}
+
+		int compareEntities(ObjEntity e1, ObjEntity e2) {
+			if (e1 == null) {
+				return e2 != null ? -1 : 0;
+			} else if (e2 == null) {
+				return 1;
+			}
+
+			// entity goes first if it is a direct or indirect superentity of
+			// another
+			// one
+			if (e1.isSubentityOf(e2)) {
+				return 1;
+			}
+
+			if (e2.isSubentityOf(e1)) {
+				return -1;
+			}
+
+			// sort alphabetically
+			return e1.getName().compareTo(e2.getName());
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/PropertyListSerialization.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/PropertyListSerialization.java b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/PropertyListSerialization.java
index e58e62d..7393f88 100644
--- a/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/PropertyListSerialization.java
+++ b/modeler/cayenne-wocompat/src/main/java/org/apache/cayenne/wocompat/PropertyListSerialization.java
@@ -36,247 +36,229 @@ import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.wocompat.parser.Parser;
 
 /**
- * A <b>PropertyListSerialization</b> is a utility class that reads and stores files in
- * NeXT/Apple property list format. Unlike corresponding WebObjects class,
- * <code>PropertyListSerialization</code> uses standard Java collections (lists and
- * maps) to store property lists.
+ * A <b>PropertyListSerialization</b> is a utility class that reads and stores
+ * files in NeXT/Apple property list format. Unlike corresponding WebObjects
+ * class, <code>PropertyListSerialization</code> uses standard Java collections
+ * (lists and maps) to store property lists.
  * 
  */
 public class PropertyListSerialization {
 
-    /**
-     * Reads a property list file. Returns a property list object, that is normally a
-     * java.util.List or a java.util.Map, but can also be a String or a Number.
-     */
-    public static Object propertyListFromFile(File f) throws FileNotFoundException {
-        return propertyListFromFile(f, null);
-    }
-
-    /**
-     * Reads a property list file. Returns a property list object, that is normally a
-     * java.util.List or a java.util.Map, but can also be a String or a Number.
-     */
-    public static Object propertyListFromFile(File f, PlistDataStructureFactory factory)
-            throws FileNotFoundException {
-        if (!f.isFile()) {
-            throw new FileNotFoundException("No such file: " + f);
-        }
-
-        return new Parser(f, factory).propertyList();
-    }
-
-    /**
-     * Reads a property list data from InputStream. Returns a property list o bject, that
-     * is normally a java.util.List or a java.util.Map, but can also be a String or a
-     * Number.
-     */
-    public static Object propertyListFromStream(InputStream in) {
-        return propertyListFromStream(in, null);
-    }
-
-    /**
-     * Reads a property list data from InputStream. Returns a property list o bject, that
-     * is normally a java.util.List or a java.util.Map, but can also be a String or a
-     * Number.
-     */
-    public static Object propertyListFromStream(
-            InputStream in,
-            PlistDataStructureFactory factory) {
-        return new Parser(in, factory).propertyList();
-    }
-
-    /**
-     * Saves property list to file.
-     */
-    public static void propertyListToFile(File f, Object plist) {
-        try {
-            BufferedWriter out = new BufferedWriter(new FileWriter(f));
-            try {
-                writeObject("", out, plist);
-            }
-            finally {
-                out.close();
-            }
-        }
-        catch (IOException ioex) {
-            throw new CayenneRuntimeException("Error saving plist.", ioex);
-        }
-    }
-
-    /**
-     * Saves property list to file.
-     */
-    public static void propertyListToStream(OutputStream os, Object plist) {
-        try {
-            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(os));
-            try {
-                writeObject("", out, plist);
-            }
-            finally {
-                out.close();
-            }
-        }
-        catch (IOException ioex) {
-            throw new CayenneRuntimeException("Error saving plist.", ioex);
-        }
-    }
-
-    /**
-     * Internal method to recursively write a property list object.
-     */
-    protected static void writeObject(String offset, Writer out, Object plist)
-            throws IOException {
-        if (plist == null) {
-            return;
-        }
-
-        if (plist instanceof Collection) {
-            Collection list = (Collection) plist;
-
-            out.write('\n');
-            out.write(offset);
-
-            if (list.size() == 0) {
-                out.write("()");
-                return;
-            }
-
-            out.write("(\n");
-
-            String childOffset = offset + "   ";
-            Iterator it = list.iterator();
-            boolean appended = false;
-            while (it.hasNext()) {
-                // Java collections can contain nulls, skip them
-                Object obj = it.next();
-                if (obj != null) {
-                    if (appended) {
-                        out.write(", \n");
-                    }
-
-                    out.write(childOffset);
-                    writeObject(childOffset, out, obj);
-                    appended = true;
-                }
-            }
-
-            out.write('\n');
-            out.write(offset);
-            out.write(')');
-        }
-        else if (plist instanceof Map) {
-            Map map = (Map) plist;
-            out.write('\n');
-            out.write(offset);
-
-            if (map.size() == 0) {
-                out.write("{}");
-                return;
-            }
-
-            out.write("{");
-
-            String childOffset = offset + "    ";
-
-            Iterator it = map.entrySet().iterator();
-            while (it.hasNext()) {
-                // Java collections can contain nulls, skip them
-                Map.Entry entry = (Map.Entry) it.next();
-                Object key = entry.getKey();
-                if (key == null) {
-                    continue;
-                }
-                Object obj = entry.getValue();
-                if (obj == null) {
-                    continue;
-                }
-                out.write('\n');
-                out.write(childOffset);
-                out.write(quoteString(key.toString()));
-                out.write(" = ");
-                writeObject(childOffset, out, obj);
-                out.write(';');
-            }
-
-            out.write('\n');
-            out.write(offset);
-            out.write('}');
-        }
-        else if (plist instanceof String) {
-            out.write(quoteString(plist.toString()));
-        }
-        else if (plist instanceof Number) {
-            out.write(plist.toString());
-        }
-        else {
-            throw new CayenneRuntimeException(
-                    "Unsupported class for property list serialization: "
-                            + plist.getClass().getName());
-        }
-    }
-
-    /**
-     * Escapes all doublequotes and backslashes.
-     */
-    protected static String escapeString(String str) {
-        char[] chars = str.toCharArray();
-        int len = chars.length;
-        StringBuilder buf = new StringBuilder(len + 3);
-
-        for (int i = 0; i < len; i++) {
-            if (chars[i] == '\"' || chars[i] == '\\') {
-                buf.append('\\');
-            }
-            buf.append(chars[i]);
-        }
-
-        return buf.toString();
-    }
-
-    /**
-     * Returns a quoted String, with all the escapes preprocessed. May return an unquoted
-     * String if it contains no special characters. The rule for a non-special character
-     * is the following:
-     * 
-     * <pre>
-     *       c &gt;= 'a' &amp;&amp; c &lt;= 'z'
-     *       c &gt;= 'A' &amp;&amp; c &lt;= 'Z'
-     *       c &gt;= '0' &amp;&amp; c &lt;= '9'
-     *       c == '_'
-     *       c == '$'
-     *       c == ':'
-     *       c == '.'
-     *       c == '/'
-     * </pre>
-     */
-    protected static String quoteString(String str) {
-        boolean shouldQuote = false;
-
-        // scan string for special chars,
-        // if we have them, string must be quoted
-
-        String noQuoteExtras = "_$:./";
-        char[] chars = str.toCharArray();
-        int len = chars.length;
-        if (len == 0) {
-            shouldQuote = true;
-        }
-        for (int i = 0; !shouldQuote && i < len; i++) {
-            char c = chars[i];
-
-            if ((c >= 'a' && c <= 'z')
-                    || (c >= 'A' && c <= 'Z')
-                    || (c >= '0' && c <= '9')
-                    || noQuoteExtras.indexOf(c) >= 0) {
-                continue;
-            }
-
-            shouldQuote = true;
-        }
-
-        str = escapeString(str);
-        return (shouldQuote) ? '\"' + str + '\"' : str;
-    }
-
-    
+	/**
+	 * Reads a property list file. Returns a property list object, that is
+	 * normally a java.util.List or a java.util.Map, but can also be a String or
+	 * a Number.
+	 */
+	public static Object propertyListFromFile(File f) throws FileNotFoundException {
+		return propertyListFromFile(f, null);
+	}
+
+	/**
+	 * Reads a property list file. Returns a property list object, that is
+	 * normally a java.util.List or a java.util.Map, but can also be a String or
+	 * a Number.
+	 */
+	public static Object propertyListFromFile(File f, PlistDataStructureFactory factory) throws FileNotFoundException {
+		if (!f.isFile()) {
+			throw new FileNotFoundException("No such file: " + f);
+		}
+
+		return new Parser(f, factory).propertyList();
+	}
+
+	/**
+	 * Reads a property list data from InputStream. Returns a property list o
+	 * bject, that is normally a java.util.List or a java.util.Map, but can also
+	 * be a String or a Number.
+	 */
+	public static Object propertyListFromStream(InputStream in) {
+		return propertyListFromStream(in, null);
+	}
+
+	/**
+	 * Reads a property list data from InputStream. Returns a property list o
+	 * bject, that is normally a java.util.List or a java.util.Map, but can also
+	 * be a String or a Number.
+	 */
+	public static Object propertyListFromStream(InputStream in, PlistDataStructureFactory factory) {
+		return new Parser(in, factory).propertyList();
+	}
+
+	/**
+	 * Saves property list to file.
+	 */
+	public static void propertyListToFile(File f, Object plist) {
+		try {
+
+			try (BufferedWriter out = new BufferedWriter(new FileWriter(f));) {
+				writeObject("", out, plist);
+			}
+		} catch (IOException ioex) {
+			throw new CayenneRuntimeException("Error saving plist.", ioex);
+		}
+	}
+
+	/**
+	 * Saves property list to file.
+	 */
+	public static void propertyListToStream(OutputStream os, Object plist) {
+		try {
+
+			try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(os));) {
+				writeObject("", out, plist);
+			}
+		} catch (IOException ioex) {
+			throw new CayenneRuntimeException("Error saving plist.", ioex);
+		}
+	}
+
+	/**
+	 * Internal method to recursively write a property list object.
+	 */
+	protected static void writeObject(String offset, Writer out, Object plist) throws IOException {
+		if (plist == null) {
+			return;
+		}
+
+		if (plist instanceof Collection) {
+			Collection list = (Collection) plist;
+
+			out.write('\n');
+			out.write(offset);
+
+			if (list.size() == 0) {
+				out.write("()");
+				return;
+			}
+
+			out.write("(\n");
+
+			String childOffset = offset + "   ";
+			Iterator it = list.iterator();
+			boolean appended = false;
+			while (it.hasNext()) {
+				// Java collections can contain nulls, skip them
+				Object obj = it.next();
+				if (obj != null) {
+					if (appended) {
+						out.write(", \n");
+					}
+
+					out.write(childOffset);
+					writeObject(childOffset, out, obj);
+					appended = true;
+				}
+			}
+
+			out.write('\n');
+			out.write(offset);
+			out.write(')');
+		} else if (plist instanceof Map) {
+			Map map = (Map) plist;
+			out.write('\n');
+			out.write(offset);
+
+			if (map.size() == 0) {
+				out.write("{}");
+				return;
+			}
+
+			out.write("{");
+
+			String childOffset = offset + "    ";
+
+			Iterator it = map.entrySet().iterator();
+			while (it.hasNext()) {
+				// Java collections can contain nulls, skip them
+				Map.Entry entry = (Map.Entry) it.next();
+				Object key = entry.getKey();
+				if (key == null) {
+					continue;
+				}
+				Object obj = entry.getValue();
+				if (obj == null) {
+					continue;
+				}
+				out.write('\n');
+				out.write(childOffset);
+				out.write(quoteString(key.toString()));
+				out.write(" = ");
+				writeObject(childOffset, out, obj);
+				out.write(';');
+			}
+
+			out.write('\n');
+			out.write(offset);
+			out.write('}');
+		} else if (plist instanceof String) {
+			out.write(quoteString(plist.toString()));
+		} else if (plist instanceof Number) {
+			out.write(plist.toString());
+		} else {
+			throw new CayenneRuntimeException("Unsupported class for property list serialization: "
+					+ plist.getClass().getName());
+		}
+	}
+
+	/**
+	 * Escapes all doublequotes and backslashes.
+	 */
+	protected static String escapeString(String str) {
+		char[] chars = str.toCharArray();
+		int len = chars.length;
+		StringBuilder buf = new StringBuilder(len + 3);
+
+		for (int i = 0; i < len; i++) {
+			if (chars[i] == '\"' || chars[i] == '\\') {
+				buf.append('\\');
+			}
+			buf.append(chars[i]);
+		}
+
+		return buf.toString();
+	}
+
+	/**
+	 * Returns a quoted String, with all the escapes preprocessed. May return an
+	 * unquoted String if it contains no special characters. The rule for a
+	 * non-special character is the following:
+	 * 
+	 * <pre>
+	 *       c &gt;= 'a' &amp;&amp; c &lt;= 'z'
+	 *       c &gt;= 'A' &amp;&amp; c &lt;= 'Z'
+	 *       c &gt;= '0' &amp;&amp; c &lt;= '9'
+	 *       c == '_'
+	 *       c == '$'
+	 *       c == ':'
+	 *       c == '.'
+	 *       c == '/'
+	 * </pre>
+	 */
+	protected static String quoteString(String str) {
+		boolean shouldQuote = false;
+
+		// scan string for special chars,
+		// if we have them, string must be quoted
+
+		String noQuoteExtras = "_$:./";
+		char[] chars = str.toCharArray();
+		int len = chars.length;
+		if (len == 0) {
+			shouldQuote = true;
+		}
+		for (int i = 0; !shouldQuote && i < len; i++) {
+			char c = chars[i];
+
+			if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
+					|| noQuoteExtras.indexOf(c) >= 0) {
+				continue;
+			}
+
+			shouldQuote = true;
+		}
+
+		str = escapeString(str);
+		return (shouldQuote) ? '\"' + str + '\"' : str;
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/26d8434d/modeler/cayenne-wocompat/src/test/java/org/apache/cayenne/wocompat/EOModelHelperTest.java
----------------------------------------------------------------------
diff --git a/modeler/cayenne-wocompat/src/test/java/org/apache/cayenne/wocompat/EOModelHelperTest.java b/modeler/cayenne-wocompat/src/test/java/org/apache/cayenne/wocompat/EOModelHelperTest.java
index 0d78ea6..f2b5201 100644
--- a/modeler/cayenne-wocompat/src/test/java/org/apache/cayenne/wocompat/EOModelHelperTest.java
+++ b/modeler/cayenne-wocompat/src/test/java/org/apache/cayenne/wocompat/EOModelHelperTest.java
@@ -19,8 +19,12 @@
 
 package org.apache.cayenne.wocompat;
 
-import org.junit.Before;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -30,91 +34,86 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import org.junit.Before;
+import org.junit.Test;
 
 public class EOModelHelperTest {
 
-    protected EOModelHelper helper;
-
-    @Before
-    public void setUp() throws Exception {
-        URL url = getClass().getClassLoader().getResource("wotests/art.eomodeld/");
-        assertNotNull(url);
-        helper = new EOModelHelper(url);
-    }
-
-    @Test
-    public void testModelNames() throws Exception {
-        Iterator names = helper.modelNames();
-
-        // collect to list and then analyze
-        List list = new ArrayList();
-        while (names.hasNext()) {
-            list.add(names.next());
-        }
-
-        assertEquals(8, list.size());
-        assertTrue(list.contains("Artist"));
-        assertTrue(list.contains("Painting"));
-        assertTrue(list.contains("ExhibitType"));
-    }
-
-    @Test
-    public void testQueryNames() throws Exception {
-        Iterator artistNames = helper.queryNames("Artist");
-        assertFalse(artistNames.hasNext());
-
-        Iterator etNames = helper.queryNames("ExhibitType");
-        assertTrue(etNames.hasNext());
-
-        // collect to list and then analyze
-        List list = new ArrayList();
-        while (etNames.hasNext()) {
-            list.add(etNames.next());
-        }
-
-        assertEquals(2, list.size());
-        assertTrue(list.contains("FetchAll"));
-        assertTrue(list.contains("TestQuery"));
-    }
-
-    @Test
-    public void testQueryPListMap() throws Exception {
-        assertNull(helper.queryPListMap("Artist", "AAA"));
-        assertNull(helper.queryPListMap("ExhibitType", "AAA"));
-
-        Map query = helper.queryPListMap("ExhibitType", "FetchAll");
-        assertNotNull(query);
-        assertFalse(query.isEmpty());
-    }
-
-    @Test
-    public void testLoadQueryIndex() throws Exception {
-        Map index = helper.loadQueryIndex("ExhibitType");
-        assertNotNull(index);
-        assertTrue(index.containsKey("FetchAll"));
-    }
-
-    @Test
-    public void testOpenQueryStream() throws Exception {
-        InputStream in = helper.openQueryStream("ExhibitType");
-        assertNotNull(in);
-        in.close();
-    }
-
-    @Test
-    public void testOpenNonExistentQueryStream() throws Exception {
-        try {
-            helper.openQueryStream("Artist");
-            fail("Exception expected - artist has no fetch spec.");
-        }
-        catch (IOException ioex) {
-            // expected...
-        }
-    }
+	protected EOModelHelper helper;
+
+	@Before
+	public void setUp() throws Exception {
+		URL url = getClass().getClassLoader().getResource("wotests/art.eomodeld/");
+		assertNotNull(url);
+		helper = new EOModelHelper(url);
+	}
+
+	@Test
+	public void testModelNames() throws Exception {
+		Iterator names = helper.modelNames();
+
+		// collect to list and then analyze
+		List list = new ArrayList();
+		while (names.hasNext()) {
+			list.add(names.next());
+		}
+
+		assertEquals(8, list.size());
+		assertTrue(list.contains("Artist"));
+		assertTrue(list.contains("Painting"));
+		assertTrue(list.contains("ExhibitType"));
+	}
+
+	@Test
+	public void testQueryNames() throws Exception {
+		Iterator artistNames = helper.queryNames("Artist");
+		assertFalse(artistNames.hasNext());
+
+		Iterator etNames = helper.queryNames("ExhibitType");
+		assertTrue(etNames.hasNext());
+
+		// collect to list and then analyze
+		List list = new ArrayList();
+		while (etNames.hasNext()) {
+			list.add(etNames.next());
+		}
+
+		assertEquals(2, list.size());
+		assertTrue(list.contains("FetchAll"));
+		assertTrue(list.contains("TestQuery"));
+	}
+
+	@Test
+	public void testQueryPListMap() throws Exception {
+		assertNull(helper.queryPListMap("Artist", "AAA"));
+		assertNull(helper.queryPListMap("ExhibitType", "AAA"));
+
+		Map query = helper.queryPListMap("ExhibitType", "FetchAll");
+		assertNotNull(query);
+		assertFalse(query.isEmpty());
+	}
+
+	@Test
+	public void testLoadQueryIndex() throws Exception {
+		Map index = helper.loadQueryIndex("ExhibitType");
+		assertNotNull(index);
+		assertTrue(index.containsKey("FetchAll"));
+	}
+
+	@Test
+	public void testOpenQueryStream() throws Exception {
+		try (InputStream in = helper.openQueryStream("ExhibitType");) {
+			assertNotNull(in);
+		}
+	}
+
+	@Test
+	public void testOpenNonExistentQueryStream() throws Exception {
+		try {
+			helper.openQueryStream("Artist");
+			fail("Exception expected - artist has no fetch spec.");
+		} catch (IOException ioex) {
+			// expected...
+		}
+	}
 }


Mime
View raw message