001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * Portions Copyrighted 2007 Sun Microsystems, Inc.
027: */
028:
029: /*
030: * EJBDevelopmentInfoHelper.java
031: *
032: * Created on October 29, 2004, 11:51 AM
033: */
034:
035: package org.netbeans.modules.j2ee.sun.persistence.mapping.ejb;
036:
037: import java.lang.ref.WeakReference;
038: import java.util.*;
039: import java.io.IOException;
040:
041: import org.openide.util.Enumerations;
042: import org.openide.util.NbBundle;
043: import org.openide.filesystems.FileObject;
044:
045: import org.netbeans.modules.j2ee.dd.api.ejb.*;
046: import org.netbeans.modules.j2ee.deployment.common.api.SourceFileMap;
047: import org.netbeans.modules.dbschema.SchemaElement;
048:
049: import com.sun.jdo.api.persistence.model.Model;
050: import com.sun.jdo.spi.persistence.utility.StringHelper;
051: import com.sun.jdo.api.persistence.mapping.ejb.*;
052: import org.netbeans.modules.j2ee.sun.dd.api.cmp.SunCmpMapping;
053: import org.netbeans.modules.j2ee.sun.dd.api.cmp.SunCmpMappings;
054:
055: /** This is a class which implements the EJBInfoHelper interface
056: * based on EjbJar and other DDAPI classes.
057: *
058: * @author Rochelle Raccah
059: */
060: public class EJBDevelopmentInfoHelper implements EJBInfoHelper {
061:
062: private final ResourceBundle bundle = NbBundle
063: .getBundle(EJBDevelopmentInfoHelper.class);
064:
065: private static final char UNDERLINE = '_';
066: private static final String DBSCHEMA_EXTENSION = "dbschema"; // NOI18N
067:
068: private EjbJar bundleDescriptor;
069: private WeakReference sourceFileMapRef;
070: private DevelopmentNameMapper nameMapper; // standard one
071: private Model model;
072:
073: /** Creates a new instance of EJBDevelopmentInfoHelper
074: * @param mappings the SunCmpMappings which helps force relevant
075: * schemas into the cache.
076: * @param sourceFileMap the SourceFileMap which helps look up
077: * source roots in the project.
078: */
079: public EJBDevelopmentInfoHelper(SunCmpMappings mappings,
080: SourceFileMap sourceFileMap) {
081: this (mappings, sourceFileMap, null, null);
082: }
083:
084: /** Creates a new instance of EJBDevelopmentInfoHelper
085: * @param mappings the SunCmpMappings which helps force relevant
086: * schemas into the cache.
087: * @param sourceFileMap the SourceFileMap which helps look up
088: * source roots in the project.
089: */
090: EJBDevelopmentInfoHelper(SunCmpMappings mappings,
091: SourceFileMap sourceFileMap,
092: DevelopmentNameMapper nameMapper, Model model) {
093: this .setSourceFileMap(sourceFileMap);
094: this .nameMapper = nameMapper;
095: this .model = model;
096: putSchemasInCache(mappings);
097: }
098:
099: /** Gets the EjbJar which defines the universe of
100: * names for this application.
101: * @return the EjbJar which defines the universe of
102: * names for this application.
103: */
104: private EjbJar getBundleDescriptor() {
105: if (bundleDescriptor == null) {
106: try {
107: FileObject[] result = getSourceFileMap()
108: .findSourceFile("ejb-jar.xml"); // NOI18N
109:
110: if ((result != null) && (result.length > 0)) {
111: bundleDescriptor = DDProvider.getDefault()
112: .getDDRoot(result[0]);
113: } else {
114: // no ejb-jar.xml
115: throw new IllegalStateException(bundle
116: .getString("ERR_EjbJarRequired")); // NOI18N
117: }
118: } catch (IOException ioe) {
119: // TODO this is really a problem - should we throw a
120: //RuntimeException? for now, at least log the cause
121: ioe.printStackTrace();// will return null
122: }
123: }
124:
125: return bundleDescriptor;
126: }
127:
128: private FileObject[] getSourceRoots() {
129: return getSourceFileMap().getSourceRoots();
130: }
131:
132: /** Gets the name of the ejb bundle.
133: * @return the name of the ejb bundle
134: */
135: public String getEjbJarDisplayName() {
136: // TODO: this other call needs locale:
137: // return getBundleDescriptor().getDisplayName();
138: // which method should be used?
139: return getBundleDescriptor().getDefaultDisplayName();
140: }
141:
142: /** Gets a collection of names of schemas defined in this
143: * ejb jar.
144: * @return a collection schema names
145: */
146: public Collection getAvailableSchemaNames() {
147: FileObject[] sourceRoots = getSourceRoots();
148: ArrayList returnList = new ArrayList();
149: int i, count = ((sourceRoots != null) ? sourceRoots.length : 0);
150:
151: for (i = 0; i < count; i++) {
152: Enumeration allSchemaFiles = getAllOfType(sourceRoots[i],
153: DBSCHEMA_EXTENSION);
154:
155: while (allSchemaFiles.hasMoreElements()) {
156: FileObject next = (FileObject) allSchemaFiles
157: .nextElement();
158:
159: returnList.add(getSourceFileMap().getDistributionPath(
160: next).getPath());
161: }
162: }
163:
164: return returnList;
165: }
166:
167: private Enumeration getAllOfType(FileObject from, final String ext) {
168: return Enumerations.filter(from.getChildren(true),
169: new Enumerations.Processor() {
170: public Object process(Object obj,
171: Collection allwaysNull) {
172: return ((FileObject) obj).hasExt(ext) ? obj
173: : null;
174: }
175: });
176: }
177:
178: public String getSchemaNameToGenerate() {
179: return getSourceFileMap().getContextName() + UNDERLINE
180: + getEjbJarDisplayName();
181: }
182:
183: /** Gets the schema with the specified name, loading it if necessary.
184: * This implementation uses the file object source roots as the extra
185: * context information used to load.
186: * @param schemaName the name of the schema to be loaded
187: * @return the schema object
188: */
189: public SchemaElement getSchema(String schemaName) {
190: return SchemaElement.forName(schemaName, getSourceRoots());
191: }
192:
193: // cmps only
194: public Collection getEjbNames() {
195: EnterpriseBeans allBeans = getBundleDescriptor()
196: .getEnterpriseBeans();
197: Entity[] entityBeans = allBeans.getEntity();
198: int i, count = ((entityBeans != null) ? entityBeans.length : 0);
199: ArrayList returnList = new ArrayList();
200:
201: for (i = 0; i < count; i++) {
202: Entity ejb = entityBeans[i];
203:
204: if (Entity.PERSISTENCE_TYPE_CONTAINER.equals(ejb
205: .getPersistenceType())) {
206: returnList.add(ejb.getEjbName());
207: }
208: }
209:
210: return returnList;
211: }
212:
213: public Collection getFieldsForEjb(String ejbName) {
214: return getNameMapperInternal().getFieldsForEjb(ejbName);
215: }
216:
217: public Collection getRelationshipsForEjb(String ejbName) {
218: return getNameMapperInternal().getRelationshipFieldsForEjb(
219: ejbName);
220: }
221:
222: /** Gets the class loader which corresponds to this ejb bundle.
223: * @return the class loader which corresponds to this ejb bundle
224: */
225: public ClassLoader getClassLoader() {
226: // TODO: not sure if this should really be null
227: return null;//getBundleDescriptor().getClassLoader();
228: }
229:
230: public AbstractNameMapper getNameMapper() {
231: return getNameMapperInternal();
232: }
233:
234: public AbstractNameMapper createUniqueNameMapper() {
235: // TODO: this is NOT OKAY to have 2 diff instances neither
236: // of which does expand pc class names
237: // need to move expandpc names from namemapper subclass to superclass
238: // need to get a name mapper which returns diff pc class names to
239: // be used as *unique* table names
240: // right now, at ejbc time/dt time, DOL provides the hash code that makes
241: // pc class names unique, but we could provide an alternative
242: // deployment creation of tables would use dbschema table names, so
243: // 2 diff algorithms to create unique names would be okay
244: return new DevelopmentNameMapper(getBundleDescriptor());
245: }
246:
247: private DevelopmentNameMapper getNameMapperInternal() {
248: if (nameMapper == null)
249: nameMapper = new DevelopmentNameMapper(
250: getBundleDescriptor());
251:
252: return nameMapper;
253: }
254:
255: public ConversionHelper createConversionHelper() {
256: return new DevelopmentConversionHelper(getNameMapperInternal(),
257: getModel());
258: }
259:
260: public Model getModel() {
261: if (model == null) {
262: model = new EJBDevelopmentModel(getNameMapperInternal(),
263: getClassLoader(), getSourceRoots());
264: }
265:
266: return model;
267: }
268:
269: // we must load all schemas into the cache
270: // while we know the sourceroot context
271: private void putSchemasInCache(SunCmpMappings mappings) {
272: if (mappings != null) {
273: SunCmpMapping[] mapping = mappings.getSunCmpMapping();
274: int i, count = ((mapping != null) ? mapping.length : 0);
275:
276: for (i = 0; i < count; i++) {
277: String schemaName = mapping[i].getSchema();
278:
279: if (!StringHelper.isEmpty(schemaName))
280: getSchema(schemaName.trim());
281: }
282: }
283: }
284:
285: private SourceFileMap getSourceFileMap() {
286: SourceFileMap sfm = null;
287: if (sourceFileMapRef != null) {
288: sfm = (SourceFileMap) sourceFileMapRef.get();
289: }
290: return sfm;
291: }
292:
293: private void setSourceFileMap(SourceFileMap sourceFileMap) {
294: this .sourceFileMapRef = new WeakReference(sourceFileMap);
295: }
296: }
|