Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/objectstyle/cayenne/wocompat/EOModelHelper.java


1   /* ====================================================================
2    * 
3    * The ObjectStyle Group Software License, Version 1.0 
4    *
5    * Copyright (c) 2002-2003 The ObjectStyle Group 
6    * and individual authors of the software.  All rights reserved.
7    *
8    * Redistribution and use in source and binary forms, with or without
9    * modification, are permitted provided that the following conditions
10   * are met:
11   *
12   * 1. Redistributions of source code must retain the above copyright
13   *    notice, this list of conditions and the following disclaimer. 
14   *
15   * 2. Redistributions in binary form must reproduce the above copyright
16   *    notice, this list of conditions and the following disclaimer in
17   *    the documentation and/or other materials provided with the
18   *    distribution.
19   *
20   * 3. The end-user documentation included with the redistribution, if
21   *    any, must include the following acknowlegement:  
22   *       "This product includes software developed by the 
23   *        ObjectStyle Group (http://objectstyle.org/)."
24   *    Alternately, this acknowlegement may appear in the software itself,
25   *    if and wherever such third-party acknowlegements normally appear.
26   *
27   * 4. The names "ObjectStyle Group" and "Cayenne" 
28   *    must not be used to endorse or promote products derived
29   *    from this software without prior written permission. For written 
30   *    permission, please contact andrus@objectstyle.org.
31   *
32   * 5. Products derived from this software may not be called "ObjectStyle"
33   *    nor may "ObjectStyle" appear in their names without prior written
34   *    permission of the ObjectStyle Group.
35   *
36   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39   * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
40   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47   * SUCH DAMAGE.
48   * ====================================================================
49   *
50   * This software consists of voluntary contributions made by many
51   * individuals on behalf of the ObjectStyle Group.  For more
52   * information on the ObjectStyle Group, please see
53   * <http://objectstyle.org/>.
54   *
55   */
56  package org.objectstyle.cayenne.wocompat;
57  
58  import java.io.InputStream;
59  import java.net.URL;
60  import java.util.Collections;
61  import java.util.HashMap;
62  import java.util.Iterator;
63  import java.util.List;
64  import java.util.Map;
65  
66  import org.objectstyle.cayenne.map.DataMap;
67  import org.objectstyle.cayenne.util.ResourceLocator;
68  import org.objectstyle.cayenne.wocompat.parser.Parser;
69  
70  /**
71   *  Helper class used by EOModelProcessor. During creation, it loads
72   *  EOModel from the specified location and parses EOModel files storing them
73   *  internally as maps. EOModelProcessor will use this information to create 
74   *  DataMap instance.
75   */
76  public class EOModelHelper {
77      private static final ResourceLocator locator = new ResourceLocator();
78  
79      private Parser plistParser = new Parser();
80      protected URL modelUrl;
81      protected Map entityIndex;
82      protected Map entityClassIndex;
83      protected DataMap dataMap;
84    private Map prototypeValues;
85  
86      static {
87          // configure locator 
88          locator.setSkipClasspath(false);
89          locator.setSkipCurrentDirectory(false);
90          locator.setSkipHomeDirectory(true);
91          locator.setSkipAbsolutePath(false);
92      }
93  
94      /** 
95       *  Creates helper instance and tries to locate 
96       *  EOModel and load index file. 
97       */
98      public EOModelHelper(String path) throws Exception {
99          // configure URL
100         modelUrl = findModelUrl(path);
101 
102         // configure name
103         dataMap = new DataMap(findModelName(path));
104 
105         // load index file
106         List modelIndex = (List) loadModelIndex().get("entities");
107 
108         // load entity indices
109         entityIndex = new HashMap();
110         entityClassIndex = new HashMap();
111 
112         Iterator it = modelIndex.iterator();
113         while (it.hasNext()) {
114             Map info = (Map) it.next();
115             String name = (String) info.get("name");
116             entityIndex.put(name, loadEntityIndex(name));
117             entityClassIndex.put(name, info.get("className"));
118         }
119     }
120 
121     /** Performs Objective C data types conversion to Java types.
122      * 
123      *  @return String representation for Java type corresponding 
124      *  to String representation of Objective C type. 
125      */
126     public String javaTypeForEOModelerType(String type) {
127         if (type == null) {
128             return null;
129         }
130 
131         if (type.equals("NSString"))
132             return "java.lang.String";
133         if (type.equals("NSNumber"))
134             return "java.lang.Integer";
135         if (type.equals("NSCalendarDate"))
136             return "java.sql.Date";
137         if (type.equals("NSDecimalNumber"))
138             return "java.math.BigDecimal";
139         if (type.equals("NSData"))
140             return "byte[]";
141 
142         // don't know what the class is mapped to... 
143         // do some minimum sanity check and use as is
144         try {
145             return Class.forName(type).getName();
146         }
147         catch (ClassNotFoundException aClassNotFoundException) {
148             try {
149                 return Class.forName("java.lang." + type).getName();
150             }
151             catch (ClassNotFoundException anotherClassNotFoundException) {
152                 try {
153                     return Class.forName("java.util." + type).getName();
154                 }
155                 catch (ClassNotFoundException yetAnotherClassNotFoundException) {
156                     try {
157                         return ClassLoader
158                             .getSystemClassLoader()
159                             .loadClass(type)
160                             .getName();
161                     }
162                     catch (ClassNotFoundException e) {
163                         throw new IllegalArgumentException("Unknown data type: " + type);
164                     }
165                 }
166             }
167         }
168     }
169 
170     /** Returns a DataMap associated with this helper. */
171     public DataMap getDataMap() {
172         return dataMap;
173     }
174 
175     /** Returns EOModel location as URL. */
176     public URL getModelUrl() {
177         return modelUrl;
178     }
179 
180     /** Returns an iterator of model names. */
181     public Iterator modelNames() {
182         return entityClassIndex.keySet().iterator();
183     }
184 
185     public Map getPrototypeAttributeMapFor(String aPrototypeAttributeName) {
186         if (prototypeValues == null) {
187 
188             Map eoPrototypesEntityMap = this.entityInfo("EOPrototypes");
189 
190             // no prototypes
191             if (eoPrototypesEntityMap == null) {
192                 prototypeValues = Collections.EMPTY_MAP;
193             }
194             else {
195                 List eoPrototypeAttributes =
196                     (List) eoPrototypesEntityMap.get("attributes");
197 
198                 prototypeValues = new HashMap();
199                 Iterator it = eoPrototypeAttributes.iterator();
200                 while (it.hasNext()) {
201                     Map attrMap = (Map) it.next();
202 
203                     String attrName = (String) attrMap.get("name");
204 
205                     Map prototypeAttrMap = new HashMap();
206                     prototypeValues.put(attrName, prototypeAttrMap);
207 
208                     prototypeAttrMap.put("name", attrMap.get("name"));
209                     prototypeAttrMap.put("prototypeName", attrMap.get("prototypeName"));
210                     prototypeAttrMap.put("columnName", attrMap.get("columnName"));
211                     prototypeAttrMap.put("valueClassName", attrMap.get("valueClassName"));
212                     prototypeAttrMap.put("width", attrMap.get("width"));
213                     prototypeAttrMap.put("allowsNull", attrMap.get("allowsNull"));
214                     prototypeAttrMap.put("scale", attrMap.get("scale"));
215                 }
216             }
217         }
218 
219         Map aMap = (Map) prototypeValues.get(aPrototypeAttributeName);
220         if (null == aMap)
221             aMap = Collections.EMPTY_MAP;
222 
223         return aMap;
224     }
225 
226     /** Returns an info map for the entity called <code>entityName</code>. */
227     public Map entityInfo(String entityName) {
228         return (Map) entityIndex.get(entityName);
229     }
230 
231     /** Returns an info map for the entity called <code>entityName</code>. */
232     public String entityClass(String entityName) {
233         return (String) entityClassIndex.get(entityName);
234     }
235 
236     /** Loads EOModel index and returns it as a map. */
237     protected Map loadModelIndex() throws Exception {
238         InputStream indexIn = openIndexStream();
239         try {
240             plistParser.ReInit(indexIn);
241             return (Map) plistParser.propertyList();
242         }
243         finally {
244             indexIn.close();
245         }
246     }
247 
248     /** Loads EOEntity information and returns it as a map. */
249     protected Map loadEntityIndex(String entityName) throws Exception {
250         InputStream entIn = openEntityStream(entityName);
251         try {
252             plistParser.ReInit(entIn);
253             return (Map) plistParser.propertyList();
254         }
255         finally {
256             entIn.close();
257         }
258     }
259 
260     /** Returns EOModel name based on its path. */
261     protected String findModelName(String path) {
262         // strip trailing slashes
263         if (path.endsWith("/") || path.endsWith("\\")) {
264             path = path.substring(0, path.length() - 1);
265         }
266 
267         // strip path components
268         int i1 = path.lastIndexOf("/");
269         int i2 = path.lastIndexOf("\\");
270         int i = (i1 > i2) ? i1 : i2;
271         if (i >= 0) {
272             path = path.substring(i + 1);
273         }
274 
275         // strip .eomodeld suffix
276         if (path.endsWith(".eomodeld")) {
277             path = path.substring(0, path.length() - ".eomodeld".length());
278         }
279 
280         return path;
281     }
282 
283     /** Returns a URL of the EOModel directory. Throws exception if it 
284      *  can't be found. */
285     protected URL findModelUrl(String path) {
286         if (!path.endsWith(".eomodeld")) {
287             path += ".eomodeld";
288         }
289 
290         URL base = locator.findDirectoryResource(path);
291         if (base == null) {
292             throw new IllegalArgumentException("Can't find EOModel: " + path);
293         }
294         return base;
295     }
296 
297     /** 
298      * Returns InputStream to read an EOModel index file.
299      */
300     protected InputStream openIndexStream() throws Exception {
301         return new URL(modelUrl, "index.eomodeld").openStream();
302     }
303 
304     /** Returns InputStream to read an EOEntity plist file.
305      * 
306      * @param entityName name of EOEntity to be loaded.
307      * 
308      * @return InputStream to read an EOEntity plist file or null if
309      * <code>entityname.plist</code> file can not be located.
310      */
311     protected InputStream openEntityStream(String entityName) throws Exception {
312         return new URL(modelUrl, entityName + ".plist").openStream();
313     }
314 }