001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.sql.project;
021:
022: import java.beans.PropertyChangeListener;
023: import java.beans.PropertyChangeSupport;
024: import java.io.IOException;
025: import javax.swing.Icon;
026: import javax.swing.ImageIcon;
027:
028: import org.netbeans.api.project.FileOwnerQuery;
029: import org.netbeans.api.project.Project;
030: import org.netbeans.api.project.ProjectManager;
031: import org.netbeans.api.project.ant.AntArtifact;
032: import org.netbeans.api.project.ProjectInformation;
033: import org.netbeans.modules.sql.project.spi.JbiArtifactProvider;
034: import org.netbeans.modules.compapp.projects.base.ui.IcanproCustomizerProvider;
035: import org.netbeans.modules.compapp.projects.base.ui.IcanproLogicalViewProvider;
036: import org.netbeans.modules.compapp.projects.base.ui.customizer.IcanproProjectProperties;
037: import org.netbeans.spi.project.SubprojectProvider;
038: import org.netbeans.spi.project.support.ant.AntProjectEvent;
039: import org.netbeans.spi.project.support.ant.AntProjectHelper;
040: import org.netbeans.spi.project.support.ant.AntProjectListener;
041: import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
042: import org.netbeans.spi.project.support.ant.ProjectXmlSavedHook;
043: import org.netbeans.spi.project.ui.PrivilegedTemplates;
044: import org.netbeans.spi.project.ui.RecommendedTemplates;
045: import org.netbeans.spi.project.support.ant.ReferenceHelper;
046: import org.netbeans.spi.project.support.ant.PropertyEvaluator;
047: import org.netbeans.spi.project.support.ant.SourcesHelper;
048: import org.netbeans.spi.project.ui.ProjectOpenedHook;
049: import org.netbeans.spi.queries.FileBuiltQueryImplementation;
050: import org.openide.ErrorManager;
051: import org.openide.filesystems.FileObject;
052: import org.openide.util.Lookup;
053: import org.openide.util.Mutex;
054: import org.openide.util.Utilities;
055: import org.openide.util.lookup.Lookups;
056: import org.netbeans.spi.project.AuxiliaryConfiguration;
057: import org.w3c.dom.Element;
058: import org.w3c.dom.Node;
059: import org.w3c.dom.NodeList;
060: import org.w3c.dom.Text;
061:
062: /**
063: * Represents one ejb module project
064: * @author Chris Webster
065: */
066: public final class IcanproProject implements Project,
067: AntProjectListener {
068:
069: // private static final Icon PROJECT_ICON = new ImageIcon(Utilities.loadImage("com/sun/jbi/ui/devtoolT/projects/icanpro/ui/resources/icanproProjectIcon.gif")); // NOI18N
070: private static final Icon PROJECT_ICON = new ImageIcon(
071: Utilities
072: .loadImage("org/netbeans/modules/sql/project/ui/resources/sqlproProjectIcon.gif")); // NOI18N
073: public static final String SOURCES_TYPE_ICANPRO = "BIZPRO";
074:
075: private final AntProjectHelper helper;
076: private final PropertyEvaluator eval;
077: private final ReferenceHelper refHelper;
078: private final GeneratedFilesHelper genFilesHelper;
079: private final Lookup lookup;
080:
081: public IcanproProject(final AntProjectHelper helper)
082: throws IOException {
083: this .helper = helper;
084: eval = createEvaluator();
085: AuxiliaryConfiguration aux = helper
086: .createAuxiliaryConfiguration();
087: refHelper = new ReferenceHelper(helper, aux, helper
088: .getStandardPropertyEvaluator());
089: genFilesHelper = new GeneratedFilesHelper(helper);
090: lookup = createLookup(aux);
091: helper.addAntProjectListener(this );
092: }
093:
094: public FileObject getProjectDirectory() {
095: return helper.getProjectDirectory();
096: }
097:
098: public String toString() {
099: return "IcanproProject[" + getProjectDirectory() + "]"; // NOI18N
100: }
101:
102: private PropertyEvaluator createEvaluator() {
103: // XXX might need to use a custom evaluator to handle active platform substitutions... TBD
104: return helper.getStandardPropertyEvaluator();
105: }
106:
107: PropertyEvaluator evaluator() {
108: return eval;
109: }
110:
111: public Lookup getLookup() {
112: return lookup;
113: }
114:
115: private Lookup createLookup(AuxiliaryConfiguration aux) {
116: SubprojectProvider spp = refHelper.createSubprojectProvider();
117: FileBuiltQueryImplementation fileBuilt = helper
118: .createGlobFileBuiltQuery(helper
119: .getStandardPropertyEvaluator(),
120: new String[] { "${src.dir}/*.java" }, // NOI18N
121: new String[] { "${build.classes.dir}/*.class" } // NOI18N
122: );
123: final SourcesHelper sourcesHelper = new SourcesHelper(helper,
124: evaluator());
125: String webModuleLabel = org.openide.util.NbBundle.getMessage(
126: IcanproCustomizerProvider.class, "LBL_Node_EJBModule"); //NOI18N
127: String srcJavaLabel = org.openide.util.NbBundle.getMessage(
128: IcanproCustomizerProvider.class, "LBL_Node_Sources"); //NOI18N
129:
130: sourcesHelper.addPrincipalSourceRoot("${"
131: + IcanproProjectProperties.SOURCE_ROOT + "}",
132: webModuleLabel, /*XXX*/null, null);
133: sourcesHelper.addPrincipalSourceRoot("${"
134: + IcanproProjectProperties.SRC_DIR + "}", srcJavaLabel, /*XXX*/
135: null, null);
136:
137: sourcesHelper.addTypedSourceRoot("${"
138: + IcanproProjectProperties.SRC_DIR + "}",
139: SOURCES_TYPE_ICANPRO, srcJavaLabel, /*XXX*/null, null);
140: // sourcesHelper.addTypedSourceRoot("${"+IcanproProjectProperties.SRC_DIR+"}", JavaProjectConstants.SOURCES_TYPE_JAVA, srcJavaLabel, /*XXX*/null, null);
141: ProjectManager.mutex().postWriteRequest(new Runnable() {
142: public void run() {
143: sourcesHelper
144: .registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
145: }
146: });
147: return Lookups
148: .fixed(new Object[] {
149: new Info(),
150: aux,
151: helper.createCacheDirectoryProvider(),
152: // XXX the helper should not be exposed
153: helper,
154: spp,
155: new IcanproActionProvider(this , helper,
156: refHelper),
157: new IcanproLogicalViewProvider(this , helper,
158: evaluator(), spp, refHelper),
159: new IcanproCustomizerProvider(this , helper,
160: refHelper),
161: new JbiArtifactProviderImpl(),
162: new ProjectXmlSavedHookImpl(),
163: new ProjectOpenedHookImpl(),
164: fileBuilt,
165: new RecommendedTemplatesImpl(),
166: refHelper,
167: sourcesHelper.createSources(),
168: helper
169: .createSharabilityQuery(
170: evaluator(),
171: new String[] { "${"
172: + IcanproProjectProperties.SOURCE_ROOT
173: + "}" },
174: new String[] {
175: "${"
176: + IcanproProjectProperties.BUILD_DIR
177: + "}",
178: "${"
179: + IcanproProjectProperties.DIST_DIR
180: + "}" }) });
181: }
182:
183: public void configurationXmlChanged(AntProjectEvent ev) {
184: if (ev.getPath().equals(AntProjectHelper.PROJECT_XML_PATH)) {
185: // Could be various kinds of changes, but name & displayName might have changed.
186: Info info = (Info) getLookup().lookup(
187: ProjectInformation.class);
188: info.firePropertyChange(ProjectInformation.PROP_NAME);
189: info
190: .firePropertyChange(ProjectInformation.PROP_DISPLAY_NAME);
191: }
192: }
193:
194: public void propertiesChanged(AntProjectEvent ev) {
195: // currently ignored
196: //TODO: should not be ignored!
197: }
198:
199: String getBuildXmlName() {
200: String storedName = helper.getStandardPropertyEvaluator()
201: .getProperty(IcanproProjectProperties.BUILD_FILE);
202: return storedName == null ? GeneratedFilesHelper.BUILD_XML_PATH
203: : storedName;
204: }
205:
206: // Package private methods -------------------------------------------------
207:
208: FileObject getSourceDirectory() {
209: String srcDir = helper.getStandardPropertyEvaluator()
210: .getProperty("src.dir"); // NOI18N
211: return helper.resolveFileObject(srcDir);
212: }
213:
214: /** Return configured project name. */
215: public String getName() {
216: return (String) ProjectManager.mutex().readAccess(
217: new Mutex.Action() {
218: public Object run() {
219: Element data = helper
220: .getPrimaryConfigurationData(true);
221: // XXX replace by XMLUtil when that has findElement, findText, etc.
222: NodeList nl = data
223: .getElementsByTagNameNS(
224: SQLproProjectType.PROJECT_CONFIGURATION_NAMESPACE,
225: "name");
226: if (nl.getLength() == 1) {
227: nl = nl.item(0).getChildNodes();
228: if (nl.getLength() == 1
229: && nl.item(0).getNodeType() == Node.TEXT_NODE) {
230: return ((Text) nl.item(0))
231: .getNodeValue();
232: }
233: }
234: return "???"; // NOI18N
235: }
236: });
237: }
238:
239: // Private innerclasses ----------------------------------------------------
240:
241: private final class Info implements ProjectInformation {
242:
243: private final PropertyChangeSupport pcs = new PropertyChangeSupport(
244: this );
245:
246: Info() {
247: }
248:
249: void firePropertyChange(String prop) {
250: pcs.firePropertyChange(prop, null, null);
251: }
252:
253: public String getName() {
254: return IcanproProject.this .getName();
255: }
256:
257: public String getDisplayName() {
258: return IcanproProject.this .getName();
259: }
260:
261: public Icon getIcon() {
262: return PROJECT_ICON;
263: }
264:
265: public Project getProject() {
266: return IcanproProject.this ;
267: }
268:
269: public void addPropertyChangeListener(
270: PropertyChangeListener listener) {
271: pcs.addPropertyChangeListener(listener);
272: }
273:
274: public void removePropertyChangeListener(
275: PropertyChangeListener listener) {
276: pcs.removePropertyChangeListener(listener);
277: }
278:
279: }
280:
281: private final class ProjectXmlSavedHookImpl extends
282: ProjectXmlSavedHook {
283:
284: ProjectXmlSavedHookImpl() {
285: }
286:
287: protected void projectXmlSaved() throws IOException {
288: genFilesHelper.refreshBuildScript(
289: GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
290: IcanproProject.class
291: .getResource("resources/build-impl.xsl"),
292: false);
293: genFilesHelper.refreshBuildScript(getBuildXmlName(),
294: IcanproProject.class
295: .getResource("resources/build.xsl"), false);
296: }
297:
298: }
299:
300: private final class ProjectOpenedHookImpl extends ProjectOpenedHook {
301:
302: ProjectOpenedHookImpl() {
303: }
304:
305: protected void projectOpened() {
306: try {
307: // Check up on build scripts.
308: genFilesHelper
309: .refreshBuildScript(
310: GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
311: IcanproProject.class
312: .getResource("resources/build-impl.xsl"),
313: true);
314: genFilesHelper.refreshBuildScript(getBuildXmlName(),
315: IcanproProject.class
316: .getResource("resources/build.xsl"),
317: true);
318: } catch (IOException e) {
319: ErrorManager.getDefault().notify(
320: ErrorManager.INFORMATIONAL, e);
321: }
322:
323: if (IcanproLogicalViewProvider.hasBrokenLinks(helper,
324: refHelper)) {
325: // BrokenReferencesSupport.showAlert();
326: }
327: }
328:
329: protected void projectClosed() {
330: // Probably unnecessary, but just in case:
331: try {
332: ProjectManager.getDefault().saveProject(
333: IcanproProject.this );
334: } catch (IOException e) {
335: ErrorManager.getDefault().notify(e);
336: }
337: }
338:
339: }
340:
341: /**
342: * Exports the main JAR as an official build product for use from other scripts.
343: * The type of the artifact will be {@link AntArtifact}.
344: */
345: private final class JbiArtifactProviderImpl implements
346: JbiArtifactProvider {
347:
348: public AntArtifact[] getBuildArtifacts() {
349: return new AntArtifact[] { helper
350: .createSimpleAntArtifact(
351: JbiArtifactProvider.ARTIFACT_TYPE_JBI_ASA
352: + ":"
353: + helper
354: .getStandardPropertyEvaluator()
355: .getProperty(
356: IcanproProjectProperties.JBI_SETYPE_PREFIX),
357: IcanproProjectProperties.SE_DEPLOYMENT_JAR,
358: helper.getStandardPropertyEvaluator(),
359: "dist_se", "clean"), // NOI18N
360: };
361: }
362:
363: public String getJbiServiceAssemblyType() {
364: return helper.getStandardPropertyEvaluator().getProperty(
365: IcanproProjectProperties.JBI_SETYPE_PREFIX);
366: }
367: }
368:
369: private static final class RecommendedTemplatesImpl implements
370: RecommendedTemplates, PrivilegedTemplates {
371:
372: // List of primarily supported templates
373:
374: private static final String[] TYPES = new String[] { "XML", // NOI18N
375: "simple-files" // NOI18N
376: };
377:
378: private static final String[] PRIVILEGED_NAMES = new String[] {
379: "Templates/CAPS/schema.xsd",
380: "Templates/CAPS/untitled.bpel",
381: "Templates/CAPS/untitled.wsdl" };
382:
383: public String[] getRecommendedTypes() {
384: return TYPES;
385: }
386:
387: public String[] getPrivilegedTemplates() {
388: return PRIVILEGED_NAMES;
389: }
390:
391: }
392: }
|