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: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.compapp.projects.jbi;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.io.InputStream;
047: import java.util.ArrayList;
048: import java.util.List;
049: import java.util.logging.Logger;
050: import javax.xml.parsers.DocumentBuilder;
051: import javax.xml.parsers.DocumentBuilderFactory;
052: import org.netbeans.api.project.Project;
053: import org.netbeans.api.project.ProjectInformation;
054: import org.netbeans.modules.compapp.projects.jbi.descriptor.XmlUtil;
055: import org.netbeans.modules.compapp.projects.jbi.ui.customizer.JbiProjectProperties;
056: import org.netbeans.modules.compapp.projects.jbi.ui.customizer.VisualClassPathItem;
057: import org.openide.DialogDisplayer;
058: import org.openide.NotifyDescriptor;
059: import org.openide.cookies.SaveCookie;
060: import org.openide.filesystems.FileObject;
061: import org.openide.filesystems.FileUtil;
062: import org.openide.filesystems.Repository;
063: import org.openide.loaders.DataObject;
064: import org.openide.loaders.DataObjectNotFoundException;
065: import org.openide.util.NbBundle;
066: import org.w3c.dom.Document;
067: import org.w3c.dom.Element;
068: import org.w3c.dom.NodeList;
069:
070: import static org.netbeans.modules.compapp.projects.jbi.CasaConstants.*;
071:
072: /**
073: * A helper class to handle CASA related functions.
074: *
075: * @author jqian
076: */
077: public class CasaHelper {
078: public static String CASA_DIR_NAME = "/src/conf/"; // NOI18N
079: public static String CASA_EXT = ".casa"; // NOI18N
080: private static String WSDL_EXT = ".wsdl"; // NOI18N
081: private static String LOCK_FILE_PREFIX = ".LCK"; // NOI18N
082: private static String LOCK_FILE_SUFFIX = "~"; // NOI18N
083:
084: private static final Logger LOG = Logger
085: .getLogger("org.netbeans.modules.compapp.projects.jbi.CasaHelper");
086:
087: /**
088: * Gets the name of the CASA file in the given project.
089: *
090: * @param project a JBI project
091: *
092: * @return CASA file name
093: */
094: public static String getCasaFileName(Project project) {
095: ProjectInformation projInfo = project.getLookup().lookup(
096: ProjectInformation.class);
097: String projName = projInfo.getName();
098:
099: File pf = FileUtil.toFile(project.getProjectDirectory());
100: return pf.getPath() + CASA_DIR_NAME + projName + CASA_EXT;
101: }
102:
103: /**
104: * Gets the CASA file object in the given JBI project.
105: *
106: * @param project a JBI project
107: * @param create if <code>true</code> and the CASA file doesn't exist in
108: * the project, then an empty CASA file will be created
109: *
110: * @return CASA file object
111: */
112: public static FileObject getCasaFileObject(JbiProject project,
113: boolean create) {
114: ProjectInformation projInfo = project.getLookup().lookup(
115: ProjectInformation.class);
116: assert projInfo != null;
117:
118: String projName = projInfo.getName();
119:
120: FileObject confFO = project.getProjectDirectory()
121: .getFileObject(CASA_DIR_NAME);
122: if (confFO == null) {
123: // This could happen during compapp rename with directory name change.
124: return null;
125: }
126:
127: FileObject casaFO = confFO.getFileObject(projName + CASA_EXT);
128:
129: if (casaFO == null && create) {
130: casaFO = createDefaultCasaFileObject(project);
131: updateCasaWithJBIModules(project);
132: }
133:
134: return casaFO;
135: }
136:
137: /**
138: * Creates the default CASA file object in the JBI project.
139: *
140: * @param project a JBI project
141: *
142: * @return the newly created CASA file object
143: */
144: public static FileObject createDefaultCasaFileObject(
145: JbiProject project) {
146: ProjectInformation projInfo = project.getLookup().lookup(
147: ProjectInformation.class);
148: assert projInfo != null;
149: String projName = projInfo.getName();
150: FileObject confFO = project.getProjectDirectory()
151: .getFileObject(CASA_DIR_NAME);
152: FileObject casaFO = null;
153: try {
154: casaFO = FileUtil.copyFile(Repository.getDefault()
155: .getDefaultFileSystem().findResource(
156: "org-netbeans-modules-compapp-projects-jbi/project.casa" // NOI18N
157: ), confFO, projName);
158: // registerCasaFileListener(project);
159: } catch (IOException ex) {
160: ex.printStackTrace();
161: }
162:
163: return casaFO;
164: }
165:
166: public static FileObject getCompAppWSDLFileObject(Project project) {
167: ProjectInformation projInfo = project.getLookup().lookup(
168: ProjectInformation.class);
169: String projName = projInfo.getName();
170: FileObject srcDirFO = ((JbiProject) project)
171: .getSourceDirectory();
172: return srcDirFO == null ? null : srcDirFO
173: .getFileObject(projName + WSDL_EXT); // NOI18N
174: }
175:
176: /**
177: * Checks whether the CASA file contains any non-deleted defined WSDL Port.
178: */
179: public static boolean containsWSDLPort(JbiProject project) {
180: FileObject casaFO = getCasaFileObject(project, false);
181: if (casaFO != null) {
182: InputStream is = null;
183: try {
184: DocumentBuilderFactory builderFactory = DocumentBuilderFactory
185: .newInstance();
186: DocumentBuilder builder = builderFactory
187: .newDocumentBuilder();
188:
189: is = casaFO.getInputStream();
190: Document doc = builder.parse(is);
191:
192: NodeList endpointNodeList = doc
193: .getElementsByTagName(CASA_ENDPOINT_ELEM_NAME);
194: NodeList portNodeList = doc
195: .getElementsByTagName(CASA_PORT_ELEM_NAME);
196: for (int i = 0; i < portNodeList.getLength(); i++) {
197: Element port = (Element) portNodeList.item(i);
198: String state = port
199: .getAttribute(CASA_STATE_ATTR_NAME);
200: if (!state.equals(CASA_DELETED_ATTR_VALUE)) {
201: Element consumes = (Element) port
202: .getElementsByTagName(
203: CASA_CONSUMES_ELEM_NAME)
204: .item(0);
205: String endpointName = consumes
206: .getAttribute(CASA_ENDPOINT_ATTR_NAME);
207:
208: for (int j = 0; j < endpointNodeList
209: .getLength(); j++) {
210: Element endpoint = (Element) endpointNodeList
211: .item(j);
212: if (endpoint.getAttribute(
213: CASA_NAME_ATTR_NAME).equals(
214: endpointName)) {
215: String interfaceName = endpoint
216: .getAttribute(CASA_INTERFACE_NAME_ATTR_NAME);
217: if (interfaceName.endsWith(":"
218: + CASA_DUMMY_PORTTYPE)) { // NOI18N
219: break;
220: } else {
221: return true;
222: }
223: }
224: }
225: }
226: }
227: } catch (Exception e) {
228: System.out.println("Error parsing CASA file: " + e); // NOI18N
229: } finally {
230: if (is != null) {
231: try {
232: is.close();
233: } catch (Exception ignore) {
234: }
235: }
236: }
237: }
238: return false;
239: }
240:
241: // public static void registerCasaFileListener(JbiProject project) {
242: // FileObject casaFO = CasaHelper.getCasaFileObject(project, false);
243: // if (casaFO != null) {
244: // FileChangeListener listener =
245: // project.getLookup().lookup(FileChangeListener.class);
246: // if (listener != null) {
247: // casaFO.removeFileChangeListener(listener);
248: // casaFO.addFileChangeListener(listener);
249: // }
250: // }
251: // }
252:
253: public static void saveCasa(JbiProject project) {
254: //System.out.println("CasaHelper.saveCasa() (" + Thread.currentThread().getName() + ")");
255:
256: FileObject casaFO = getCasaFileObject(project, false);
257: if (casaFO != null) {
258: try {
259: DataObject casaDO = DataObject.find(casaFO);
260:
261: SaveCookie saveCookie = casaDO
262: .getCookie(SaveCookie.class);
263: if (saveCookie != null) {
264: try {
265: saveCookie.save();
266: } catch (IOException ex) {
267: ex.printStackTrace();
268: }
269: }
270: } catch (DataObjectNotFoundException ex) {
271: ex.printStackTrace();
272: }
273: }
274: }
275:
276: /**
277: * Updates CASA FileObject with service engine service unit info
278: * defined in the project properties.
279: *
280: * @param project a JBI project
281: */
282: public static void updateCasaWithJBIModules(JbiProject project) {
283: JbiProjectProperties properties = project
284: .getProjectProperties();
285: updateCasaWithJBIModules(project, properties);
286: }
287:
288: /**
289: * Updates CASA FileObject with service engine service unit info
290: * defined in the project properties.
291: *
292: * @param project a JBI project
293: * @param properties project properties (may not been persisted yet)
294: */
295: public static void updateCasaWithJBIModules(JbiProject project,
296: JbiProjectProperties properties) {
297:
298: FileObject casaFO = CasaHelper.getCasaFileObject(project, true);
299: if (casaFO == null) {
300: return;
301: }
302:
303: File casaFile = FileUtil.toFile(casaFO);
304:
305: try {
306: boolean modified = false; // whether casa is modified
307:
308: DocumentBuilderFactory factory = DocumentBuilderFactory
309: .newInstance();
310: factory.setNamespaceAware(true);
311: factory.setValidating(false);
312: DocumentBuilder builder = factory.newDocumentBuilder();
313: Document casaDocument = builder.parse(casaFile);
314:
315: Element sus = (Element) casaDocument.getElementsByTagName(
316: CasaConstants.CASA_SERVICE_UNITS_ELEM_NAME).item(0);
317: NodeList seSUs = sus
318: .getElementsByTagName(CasaConstants.CASA_SERVICE_ENGINE_SERVICE_UNIT_ELEM_NAME);
319:
320: @SuppressWarnings("unchecked")
321: List<VisualClassPathItem> newContentList = (List) properties
322: .get(JbiProjectProperties.JBI_CONTENT_ADDITIONAL);
323: @SuppressWarnings("unchecked")
324: List<String> newTargetIDs = (List) properties
325: .get(JbiProjectProperties.JBI_CONTENT_COMPONENT);
326:
327: List<String> newProjectNameList = new ArrayList<String>();
328: for (VisualClassPathItem newContent : newContentList) {
329: newProjectNameList.add(newContent.getProjectName());
330: }
331:
332: List<String> sesuUnitNameList = new ArrayList<String>();
333: for (int i = 0; i < seSUs.getLength(); i++) {
334: Element seSU = (Element) seSUs.item(i);
335: String unitName = seSU
336: .getAttribute(CasaConstants.CASA_UNIT_NAME_ATTR_NAME);
337: sesuUnitNameList.add(unitName);
338: }
339:
340: // Remove deleted service units from casa
341: for (int i = 0; i < seSUs.getLength(); i++) {
342: Element seSU = (Element) seSUs.item(i);
343: String projName = seSU
344: .getAttribute(CasaConstants.CASA_UNIT_NAME_ATTR_NAME);
345: if (!newProjectNameList.contains(projName)) {
346: sus.removeChild(seSU);
347: modified = true;
348: //System.out.println("removing old su: " + projName);
349: }
350: }
351:
352: // Add new service units to casa
353: for (VisualClassPathItem artifact : newContentList) {
354: String projName = artifact.getProjectName();
355: String artifactName = artifact.toString();
356:
357: if (!sesuUnitNameList.contains(projName)) {
358: String targetCompID = "unknown"; // NOI18N
359: for (int j = 0; j < newContentList.size(); j++) {
360: if (newContentList.get(j).toString().equals(
361: artifactName)) {
362: targetCompID = newTargetIDs.get(j);
363: break;
364: }
365: }
366: Element seSU = casaDocument
367: .createElement(CasaConstants.CASA_SERVICE_ENGINE_SERVICE_UNIT_ELEM_NAME);
368: seSU.setAttribute(CasaConstants.CASA_X_ATTR_NAME,
369: "-1"); // NOI18N
370: seSU.setAttribute(CasaConstants.CASA_Y_ATTR_NAME,
371: "-1"); // NOI18N
372: seSU.setAttribute(
373: CasaConstants.CASA_INTERNAL_ATTR_NAME,
374: "true"); // NOI18N
375: seSU.setAttribute(
376: CasaConstants.CASA_DEFINED_ATTR_NAME,
377: "false"); // NOI18N
378: seSU.setAttribute(
379: CasaConstants.CASA_UNKNOWN_ATTR_NAME,
380: "false"); // NOI18N
381: seSU
382: .setAttribute(
383: CasaConstants.CASA_NAME_ATTR_NAME,
384: projName); // NOI18N // FIXME
385: seSU.setAttribute(
386: CasaConstants.CASA_UNIT_NAME_ATTR_NAME,
387: projName); // NOI18N
388: seSU
389: .setAttribute(
390: CasaConstants.CASA_COMPONENT_NAME_ATTR_NAME,
391: targetCompID); // NOI18N
392: seSU.setAttribute(
393: CasaConstants.CASA_DESCRIPTION_ATTR_NAME,
394: "some description"); // NOI18N
395: seSU.setAttribute(
396: CasaConstants.CASA_ARTIFACTS_ZIP_ATTR_NAME,
397: artifactName);
398:
399: sus.appendChild(seSU);
400: modified = true;
401: //System.out.println("Adding new su: " + projName);
402: }
403: }
404:
405: if (modified) {
406: //System.out.println("CasaHelper: starting writing to CASA (Thread:" + Thread.currentThread().getName() + ")");
407: XmlUtil.writeToFileObject(casaFO, casaDocument);
408: //System.out.println("CasaHelper: finished writing to CASA (Thread:" + Thread.currentThread().getName() + ")");
409: }
410:
411: } catch (Exception e) {
412: e.printStackTrace();
413: }
414: }
415:
416: /**
417: * Deletes any left-over lock file on CASA and CompApp.wsdl.
418: */
419: public static void cleanupLocks(Project p) {
420: File casaLockFile = getCasaLockFile(p);
421:
422: if (casaLockFile != null && casaLockFile.exists()) {
423: String msg = NbBundle.getMessage(CasaHelper.class,
424: "CASA_LOCK_EXISTS"); // NOI18N
425: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
426: NotifyDescriptor.INFORMATION_MESSAGE);
427: DialogDisplayer.getDefault().notify(d);
428:
429: if (!casaLockFile.delete()) {
430: msg = NbBundle.getMessage(CasaHelper.class,
431: "FAIL_TO_DELETE_FILE", casaLockFile); // NOI18N
432: d = new NotifyDescriptor.Message(msg,
433: NotifyDescriptor.ERROR_MESSAGE);
434: DialogDisplayer.getDefault().notify(d);
435: }
436: }
437:
438: File compappWSDLLockFile = getCompAppWSDLLockFile(p);
439:
440: if (compappWSDLLockFile != null && compappWSDLLockFile.exists()) {
441: String msg = NbBundle.getMessage(CasaHelper.class,
442: "COMPAPP_WSDL_LOCK_EXISTS"); // NOI18N
443: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
444: NotifyDescriptor.INFORMATION_MESSAGE);
445: DialogDisplayer.getDefault().notify(d);
446:
447: if (!casaLockFile.delete()) {
448: msg = NbBundle.getMessage(CasaHelper.class,
449: "FAIL_TO_DELETE_FILE", compappWSDLLockFile); // NOI18N
450: d = new NotifyDescriptor.Message(msg,
451: NotifyDescriptor.ERROR_MESSAGE);
452: DialogDisplayer.getDefault().notify(d);
453: }
454: }
455: }
456:
457: private static File getCasaLockFile(Project project) {
458: ProjectInformation projInfo = project.getLookup().lookup(
459: ProjectInformation.class);
460: assert projInfo != null;
461:
462: String projName = projInfo.getName();
463:
464: FileObject confFO = project.getProjectDirectory()
465: .getFileObject(CASA_DIR_NAME);
466: if (confFO != null) {
467: // FileObject doesn't work:
468: // confFO.getFileObject(
469: // LOCK_FILE_PREFIX + projName + CASA_EXT + LOCK_FILE_SUFFIX);
470: File lockFile = new File(FileUtil.toFile(confFO),
471: LOCK_FILE_PREFIX + projName + CASA_EXT
472: + LOCK_FILE_SUFFIX);
473: return lockFile;
474: }
475:
476: return null;
477: }
478:
479: private static File getCompAppWSDLLockFile(Project project) {
480: ProjectInformation projInfo = project.getLookup().lookup(
481: ProjectInformation.class);
482: String projName = projInfo.getName();
483: FileObject srcDirFO = ((JbiProject) project)
484: .getSourceDirectory();
485: if (srcDirFO != null) {
486: // FileObject doesn't work:
487: // srcDirFO.getFileObject(
488: // LOCK_FILE_PREFIX + projName + WSDL_EXT + LOCK_FILE_SUFFIX);
489: File lockFile = new File(FileUtil.toFile(srcDirFO),
490: LOCK_FILE_PREFIX + projName + WSDL_EXT
491: + LOCK_FILE_SUFFIX);
492: return lockFile;
493: }
494:
495: return null;
496: }
497: }
|