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: package org.netbeans.modules.bpel.project;
020:
021: import java.beans.PropertyChangeListener;
022: import java.beans.PropertyChangeSupport;
023: import java.io.IOException;
024: import java.io.File;
025: import java.io.InputStream;
026: import java.io.OutputStream;
027: import java.io.FileNotFoundException;
028: import java.lang.ref.WeakReference;
029: import java.nio.charset.Charset;
030: import java.nio.charset.IllegalCharsetNameException;
031: import java.nio.charset.UnsupportedCharsetException;
032: import java.util.Collection;
033: import java.util.HashMap;
034: import java.util.Set;
035: import java.util.logging.Logger;
036: import javax.swing.Icon;
037: import javax.swing.ImageIcon;
038: import org.netbeans.api.java.project.JavaProjectConstants;
039: import org.netbeans.api.project.FileOwnerQuery;
040: import org.netbeans.api.project.Project;
041: import org.netbeans.api.project.ProjectManager;
042: import org.netbeans.api.project.ant.AntArtifact;
043: import org.openide.cookies.SaveCookie;
044: import org.openide.loaders.DataObject;
045: import org.openide.loaders.DataObjectNotFoundException;
046: import org.openide.filesystems.FileUtil;
047: import org.openide.filesystems.FileChangeListener;
048: import org.openide.filesystems.FileEvent;
049: import org.openide.filesystems.FileRenameEvent;
050: import org.openide.filesystems.FileAttributeEvent;
051: import org.openide.filesystems.FileLock;
052: import org.netbeans.modules.compapp.projects.base.spi.JbiArtifactProvider;
053: import org.netbeans.modules.compapp.projects.base.ui.IcanproCustomizerProvider;
054: import org.netbeans.modules.compapp.projects.base.ui.customizer.IcanproProjectProperties;
055: import org.netbeans.api.project.ProjectInformation;
056: import org.netbeans.api.queries.FileEncodingQuery;
057: import org.netbeans.modules.bpel.project.ui.IcanproLogicalViewProvider;
058: import org.netbeans.modules.compapp.projects.base.queries.IcanproProjectEncodingQueryImpl;
059: import org.netbeans.modules.compapp.projects.base.ui.IcanproXmlCustomizerProvider;
060: import org.netbeans.modules.xml.catalogsupport.DefaultProjectCatalogSupport;
061: import org.netbeans.spi.project.SubprojectProvider;
062: import org.netbeans.spi.project.support.ant.AntProjectEvent;
063: import org.netbeans.spi.project.support.ant.AntProjectHelper;
064: import org.netbeans.spi.project.support.ant.AntProjectListener;
065: import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
066: import org.netbeans.spi.project.support.ant.ProjectXmlSavedHook;
067: import org.netbeans.spi.project.ui.PrivilegedTemplates;
068: import org.netbeans.spi.project.ui.RecommendedTemplates;
069: import org.netbeans.spi.project.support.ant.ReferenceHelper;
070: import org.netbeans.spi.project.support.ant.PropertyEvaluator;
071: import org.netbeans.spi.project.support.ant.SourcesHelper;
072: import org.netbeans.spi.project.ui.ProjectOpenedHook;
073: import org.netbeans.spi.queries.FileBuiltQueryImplementation;
074: import org.openide.ErrorManager;
075: import org.openide.filesystems.FileObject;
076: import org.openide.util.Lookup;
077: import org.openide.util.Mutex;
078: import org.openide.util.Utilities;
079: import org.openide.util.lookup.Lookups;
080: import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
081: import org.netbeans.spi.project.AuxiliaryConfiguration;
082: import org.netbeans.spi.project.support.ant.EditableProperties;
083: import org.openide.modules.InstalledFileLocator;
084: import org.netbeans.modules.xml.retriever.catalog.CatalogEntry;
085: import org.netbeans.modules.xml.retriever.catalog.CatalogWriteModel;
086: import org.netbeans.modules.xml.retriever.catalog.CatalogWriteModelFactory;
087: import org.netbeans.modules.xml.xam.locator.CatalogModelException;
088: import org.netbeans.spi.project.support.ant.PropertyUtils;
089: import org.w3c.dom.Element;
090: import org.w3c.dom.Node;
091: import org.w3c.dom.NodeList;
092: import org.w3c.dom.Text;
093:
094: /**
095: * @author Chris Webster
096: */
097: public final class BpelproProject implements Project,
098: AntProjectListener, ProjectPropertyProvider {
099: private static final Icon PROJECT_ICON = new ImageIcon(
100: Utilities
101: .loadImage("org/netbeans/modules/bpel/project/resources/bpelProject.png")); // NOI18N
102: public static final String SOURCES_TYPE_BPELPRO = "BIZPRO";
103: public static final String ARTIFACT_TYPE_JBI_ASA = "CAPS.asa";
104:
105: public static final String MODULE_INSTALL_NAME = "modules/org-netbeans-modules-bpel-project.jar";
106: public static final String MODULE_INSTALL_CBN = "org.netbeans.modules.bpel.project";
107: public static final String MODULE_INSTALL_DIR = "module.install.dir";
108:
109: private static final Logger LOG = Logger
110: .getLogger(BpelproProject.class.getName());
111:
112: private final AntProjectHelper helper;
113: private final PropertyEvaluator eval;
114: private final ReferenceHelper refHelper;
115: private final GeneratedFilesHelper genFilesHelper;
116: private final Lookup lookup;
117: private final BpelSourcesRegistryHelper sourcesRegistryHelper;
118:
119: private ProjectCloseSupport projectCloseSupport;
120:
121: public BpelproProject(final AntProjectHelper helper)
122: throws IOException {
123: this .helper = helper;
124: eval = createEvaluator();
125: AuxiliaryConfiguration aux = helper
126: .createAuxiliaryConfiguration();
127: refHelper = new ReferenceHelper(helper, aux, helper
128: .getStandardPropertyEvaluator());
129: genFilesHelper = new GeneratedFilesHelper(helper);
130: lookup = createLookup(aux);
131: helper.addAntProjectListener(this );
132:
133: sourcesRegistryHelper = new BpelSourcesRegistryHelper(this );
134: projectCloseSupport = new ProjectCloseSupport();
135: }
136:
137: public FileObject getProjectDirectory() {
138: return helper.getProjectDirectory();
139: }
140:
141: public AntProjectHelper getAntProjectHelper() {
142: return helper;
143: }
144:
145: public String toString() {
146: return "BpelproProject[" + getProjectDirectory() + "]"; // NOI18N
147: }
148:
149: private PropertyEvaluator createEvaluator() {
150: return helper.getStandardPropertyEvaluator();
151: }
152:
153: public ReferenceHelper getReferenceHelper() {
154: return this .refHelper;
155: }
156:
157: PropertyEvaluator evaluator() {
158: return eval;
159: }
160:
161: public Lookup getLookup() {
162: return lookup;
163: }
164:
165: private Lookup createLookup(AuxiliaryConfiguration aux) {
166: SubprojectProvider spp = refHelper.createSubprojectProvider();
167: FileBuiltQueryImplementation fileBuilt = helper
168: .createGlobFileBuiltQuery(helper
169: .getStandardPropertyEvaluator(),
170: new String[] { "${src.dir}/*.java" }, // NOI18N
171: new String[] { "${build.classes.dir}/*.class" } // NOI18N
172: );
173: final SourcesHelper sourcesHelper = new SourcesHelper(helper,
174: evaluator());
175: String webModuleLabel = org.openide.util.NbBundle.getMessage(
176: IcanproCustomizerProvider.class, "LBL_Node_EJBModule"); //NOI18N
177: String srcJavaLabel = org.openide.util.NbBundle.getMessage(
178: IcanproCustomizerProvider.class, "LBL_Node_Sources"); //NOI18N
179:
180: sourcesHelper.addPrincipalSourceRoot("${"
181: + IcanproProjectProperties.SOURCE_ROOT + "}",
182: webModuleLabel, /*XXX*/null, null);
183: sourcesHelper.addPrincipalSourceRoot("${"
184: + IcanproProjectProperties.SRC_DIR + "}", srcJavaLabel, /*XXX*/
185: null, null);
186:
187: sourcesHelper.addTypedSourceRoot("${"
188: + IcanproProjectProperties.SRC_DIR + "}",
189: SOURCES_TYPE_BPELPRO, srcJavaLabel, /*XXX*/null, null);
190: sourcesHelper
191: .addTypedSourceRoot(
192: "${" + IcanproProjectProperties.SRC_DIR + "}",
193: org.netbeans.modules.xml.catalogsupport.ProjectConstants.SOURCES_TYPE_XML,
194: srcJavaLabel, null, null);
195:
196: ProjectManager.mutex().postWriteRequest(new Runnable() {
197: public void run() {
198: sourcesHelper
199: .registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
200: }
201: });
202: return Lookups
203: .fixed(new Object[] {
204: new Info(),
205: aux,
206: helper.createCacheDirectoryProvider(),
207: helper,
208: spp,
209: new BpelproActionProvider(this , helper,
210: refHelper),
211: new IcanproLogicalViewProvider(this , helper,
212: evaluator(), spp, refHelper),
213: // new BpelProjectCustomizerProvider(this),
214: // new IcanproCustomizerProvider(this, helper, refHelper,
215: // BpelproProjectType.PROJECT_CONFIGURATION_NAMESPACE),
216: new IcanproXmlCustomizerProvider(
217: this ,
218: helper,
219: refHelper,
220: BpelproProjectType.PROJECT_CONFIGURATION_NAMESPACE),
221:
222: new JbiArtifactProviderImpl(),
223: new ProjectXmlSavedHookImpl(),
224: new ProjectOpenedHookImpl(this ),
225: new BpelProjectOperations(this ),
226: fileBuilt,
227: new RecommendedTemplatesImpl(),
228: refHelper,
229: new IcanproProjectEncodingQueryImpl(evaluator()),
230: sourcesHelper.createSources(),
231: helper
232: .createSharabilityQuery(
233: evaluator(),
234: new String[] { "${"
235: + IcanproProjectProperties.SOURCE_ROOT
236: + "}" },
237: new String[] {
238: "${"
239: + IcanproProjectProperties.BUILD_DIR
240: + "}",
241: "${"
242: + IcanproProjectProperties.DIST_DIR
243: + "}" }),
244: new DefaultProjectCatalogSupport(this , helper,
245: refHelper), });
246: }
247:
248: public void configurationXmlChanged(AntProjectEvent ev) {
249: if (ev.getPath().equals(AntProjectHelper.PROJECT_XML_PATH)) {
250: Info info = (Info) getLookup().lookup(
251: ProjectInformation.class);
252: info.firePropertyChange(ProjectInformation.PROP_NAME);
253: info
254: .firePropertyChange(ProjectInformation.PROP_DISPLAY_NAME);
255: }
256: }
257:
258: public void propertiesChanged(AntProjectEvent ev) {
259: }
260:
261: String getBuildXmlName() {
262: String storedName = helper.getStandardPropertyEvaluator()
263: .getProperty(IcanproProjectProperties.BUILD_FILE);
264: return storedName == null ? GeneratedFilesHelper.BUILD_XML_PATH
265: : storedName;
266: }
267:
268: FileObject getSourceDirectory() {
269: String srcDir = helper.getStandardPropertyEvaluator()
270: .getProperty("src.dir"); // NOI18N
271: return helper.resolveFileObject(srcDir);
272: }
273:
274: private static long brokenAlertLastTime = 0;
275: private static boolean brokenAlertShown = false;
276: private static int BROKEN_ALERT_TIMEOUT = 1000;
277:
278: @SuppressWarnings("unchecked")
279: // NOI18N
280: public String getName() {
281: return (String) ProjectManager.mutex().readAccess(
282: new Mutex.Action() {
283: public Object run() {
284: Element data = helper
285: .getPrimaryConfigurationData(true);
286: NodeList nl = data
287: .getElementsByTagNameNS(
288: BpelproProjectType.PROJECT_CONFIGURATION_NAMESPACE,
289: "name");
290: if (nl.getLength() == 1) {
291: nl = nl.item(0).getChildNodes();
292: if (nl.getLength() == 1
293: && nl.item(0).getNodeType() == Node.TEXT_NODE) {
294: return ((Text) nl.item(0))
295: .getNodeValue();
296: }
297: }
298: return "???"; // NOI18N
299: }
300: });
301: }
302:
303: @SuppressWarnings("unchecked")
304: // NOI18N
305: public void setName(final String name) {
306: ProjectManager.mutex().writeAccess(new Mutex.Action() {
307: public Object run() {
308: Element data = helper.getPrimaryConfigurationData(true);
309: NodeList nl = data
310: .getElementsByTagNameNS(
311: BpelproProjectType.PROJECT_CONFIGURATION_NAMESPACE,
312: "name");
313: Element nameEl;
314: if (nl.getLength() == 1) {
315: nameEl = (Element) nl.item(0);
316: NodeList deadKids = nameEl.getChildNodes();
317: while (deadKids.getLength() > 0) {
318: nameEl.removeChild(deadKids.item(0));
319: }
320: } else {
321: nameEl = data
322: .getOwnerDocument()
323: .createElementNS(
324: BpelproProjectType.PROJECT_CONFIGURATION_NAMESPACE,
325: "name");
326: data.insertBefore(nameEl, data.getChildNodes()
327: .item(0));
328: }
329: nameEl.appendChild(data.getOwnerDocument()
330: .createTextNode(name));
331: helper.putPrimaryConfigurationData(data, true);
332: return null;
333: }
334: });
335: }
336:
337: public void addProjectCloseListener(ProjectCloseListener listener) {
338: projectCloseSupport.addProjectCloseListener(listener);
339: }
340:
341: public void removeProjectCloseListener(ProjectCloseListener listener) {
342: projectCloseSupport.removeProjectCloseListener(listener);
343: }
344:
345: private final class Info implements ProjectInformation {
346:
347: private final PropertyChangeSupport pcs = new PropertyChangeSupport(
348: this );
349: private WeakReference<String> cachedName = null;
350:
351: Info() {
352: }
353:
354: void firePropertyChange(String prop) {
355: pcs.firePropertyChange(prop, null, null);
356: synchronized (pcs) {
357: cachedName = null;
358: }
359: }
360:
361: public String getName() {
362: return PropertyUtils
363: .getUsablePropertyName(getDisplayName());
364: // return BpelproProject.this.getName();
365: }
366:
367: public String getDisplayName() {
368: synchronized (pcs) {
369: if (cachedName != null) {
370: String dn = cachedName.get();
371: if (dn != null) {
372: return dn;
373: }
374: }
375: }
376: String dn = BpelproProject.this .getName();
377: synchronized (pcs) {
378: cachedName = new WeakReference<String>(dn);
379: }
380: return dn;
381:
382: // return BpelproProject.this.getName();
383: }
384:
385: public Icon getIcon() {
386: return PROJECT_ICON;
387: }
388:
389: public Project getProject() {
390: return BpelproProject.this ;
391: }
392:
393: public void addPropertyChangeListener(
394: PropertyChangeListener listener) {
395: pcs.addPropertyChangeListener(listener);
396: }
397:
398: public void removePropertyChangeListener(
399: PropertyChangeListener listener) {
400: pcs.removePropertyChangeListener(listener);
401: }
402: }
403:
404: private final class ProjectXmlSavedHookImpl extends
405: ProjectXmlSavedHook {
406: ProjectXmlSavedHookImpl() {
407: }
408:
409: protected void projectXmlSaved() throws IOException {
410: genFilesHelper.refreshBuildScript(
411: GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
412: BpelproProject.class
413: .getResource("resources/build-impl.xsl"),
414: false);
415: genFilesHelper.refreshBuildScript(getBuildXmlName(),
416: BpelproProject.class
417: .getResource("resources/build.xsl"), false);
418: }
419: }
420:
421: private final class ProjectOpenedHookImpl extends ProjectOpenedHook {
422: ProjectOpenedHookImpl(Project project) {
423: }
424:
425: @SuppressWarnings("unchecked")
426: // NOI18N
427: protected void projectOpened() {
428: try {
429: genFilesHelper
430: .refreshBuildScript(
431: GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
432: BpelproProject.class
433: .getResource("resources/build-impl.xsl"),
434: true);
435: genFilesHelper.refreshBuildScript(getBuildXmlName(),
436: BpelproProject.class
437: .getResource("resources/build.xsl"),
438: true);
439: } catch (IOException e) {
440: ErrorManager.getDefault().notify(
441: ErrorManager.INFORMATIONAL, e);
442: }
443: ProjectManager.mutex().writeAccess(new Mutex.Action() {
444: public Object run() {
445: EditableProperties ep = helper
446: .getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
447: ep.setProperty("netbeans.user", System
448: .getProperty("netbeans.user"));
449: File f = InstalledFileLocator.getDefault().locate(
450: MODULE_INSTALL_NAME, MODULE_INSTALL_CBN,
451: false);
452:
453: if (f != null) {
454: ep.setProperty(MODULE_INSTALL_DIR, f
455: .getParentFile().getPath());
456: }
457: helper.putProperties(
458: AntProjectHelper.PRIVATE_PROPERTIES_PATH,
459: ep);
460:
461: // Add project encoding for old projects
462: EditableProperties projectEP = helper
463: .getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
464: if (projectEP
465: .getProperty(IcanproProjectProperties.SOURCE_ENCODING) == null) {
466: projectEP
467: .setProperty(
468: IcanproProjectProperties.SOURCE_ENCODING,
469: // FIXME: maybe we should use Charset.defaultCharset() instead?
470: // See comments in IcanproProjectEncodingQueryImpl.java
471: FileEncodingQuery
472: .getDefaultEncoding()
473: .name());
474: }
475: helper.putProperties(
476: AntProjectHelper.PROJECT_PROPERTIES_PATH,
477: projectEP);
478:
479: try {
480: ProjectManager.getDefault().saveProject(
481: BpelproProject.this );
482: } catch (IOException e) {
483: ErrorManager.getDefault().notify(e);
484: }
485: return null;
486: }
487: });
488: if (IcanproLogicalViewProvider.hasBrokenLinks(helper,
489: refHelper)) {
490: BrokenReferencesSupport.showAlert();
491: }
492:
493: checkEncoding();
494:
495: sourcesRegistryHelper.register();
496: addListenerOnCatalog();
497: }
498:
499: private void checkEncoding() {
500: // TODO m
501: // Should we show ErrorManager dialog to inform user in case wrong encoding parameter ?
502: String prop = eval
503: .getProperty(IcanproProjectProperties.SOURCE_ENCODING);
504: if (prop != null) {
505: try {
506: Charset c = Charset.forName(prop);
507: } catch (IllegalCharsetNameException e) {
508: //Broken property, log & ignore
509: LOG.warning("Illegal charset: " + prop
510: + " in project: " + // NOI18N
511: getProjectDirectory());
512: } catch (UnsupportedCharsetException e) {
513: //todo: Needs UI notification like broken references.
514: LOG.warning("Unsupported charset: " + prop
515: + " in project: " + // NOI18N
516: getProjectDirectory());
517: }
518: }
519: }
520:
521: // vlv # 96026
522: private void addListenerOnCatalog() {
523: //System.out.println();
524: //System.out.println();
525: //System.out.println("ADD LISTENER");
526: if (myCatalogListener != null) {
527: return;
528: }
529: CatalogWriteModel catalog = getCatalog();
530:
531: if (catalog == null) {
532: return;
533: }
534: myCatalogListener = new CatalogListener(
535: getProjectDirectory(), catalog);
536: catalog.getCatalogFileObject().addFileChangeListener(
537: myCatalogListener);
538: /* vlv # 111020
539: //System.out.println("== SAVE ==");
540: // save catalog.xml
541: FileObject fileObject = catalog.getCatalogFileObject();
542:
543: if (fileObject == null) {
544: return;
545: }
546: try {
547: DataObject dataObject = DataObject.find(fileObject);
548:
549: if (dataObject == null) {
550: return;
551: }
552: SaveCookie saveCookie = dataObject.getCookie(SaveCookie.class);
553:
554: if (saveCookie == null) {
555: return;
556: }
557: saveCookie.save();
558: }
559: catch (DataObjectNotFoundException e) {
560: // e.printStackTrace();
561: }
562: catch (IOException e) {
563: // e.printStackTrace();
564: }
565: */
566: }
567:
568: // vlv
569: private CatalogWriteModel getCatalog() {
570: try {
571: return CatalogWriteModelFactory.getInstance()
572: .getCatalogWriteModelForProject(
573: getProjectDirectory());
574: } catch (CatalogModelException e) {
575: return null;
576: }
577: }
578:
579: private CatalogListener myCatalogListener;
580:
581: protected void projectClosed() {
582: if (myCatalogListener != null) {
583: CatalogWriteModel catalog = getCatalog();
584:
585: if (catalog != null) {
586: catalog
587: .getCatalogFileObject()
588: .removeFileChangeListener(myCatalogListener);
589: }
590: myCatalogListener = null;
591: }
592: try {
593: ProjectManager.getDefault().saveProject(
594: BpelproProject.this );
595: } catch (IOException e) {
596: ErrorManager.getDefault().notify(e);
597: }
598: sourcesRegistryHelper.unregister();
599: projectCloseSupport.fireProjectClosed();
600: }
601: }
602:
603: private final class JbiArtifactProviderImpl implements
604: JbiArtifactProvider {
605: public AntArtifact[] getBuildArtifacts() {
606: return new AntArtifact[] {
607: helper
608: .createSimpleAntArtifact(
609: BpelproProject.ARTIFACT_TYPE_JBI_ASA
610: + ":"
611: + helper
612: .getStandardPropertyEvaluator()
613: .getProperty(
614: IcanproProjectProperties.JBI_SE_TYPE),
615: IcanproProjectProperties.SE_DEPLOYMENT_JAR,
616: helper
617: .getStandardPropertyEvaluator(),
618: "dist_se", "clean"), // NOI18N
619: helper.createSimpleAntArtifact(
620: JavaProjectConstants.ARTIFACT_TYPE_JAR,
621: IcanproProjectProperties.SE_DEPLOYMENT_JAR,
622: helper.getStandardPropertyEvaluator(),
623: "dist_se", "clean"), // NOI18N
624: };
625: }
626:
627: public String getJbiServiceAssemblyType() {
628: return helper.getStandardPropertyEvaluator().getProperty(
629: IcanproProjectProperties.JBI_SE_TYPE);
630: }
631: }
632:
633: private static final class RecommendedTemplatesImpl implements
634: RecommendedTemplates, PrivilegedTemplates {
635:
636: private static final String[] TYPES = new String[] {
637: "SOA_BPEL", // NOI18N
638: "XML", // NOI18N
639: "simple-files" // NOI18N
640: };
641:
642: private static final String[] PRIVILEGED_NAMES = new String[] {
643: "Templates/SOA_BPEL/Process.bpel", // NOI18N
644: "Templates/XML/retrieveXMLResource", // NOI18N
645: "Templates/XML/WSDL.wsdl", // NOI18N
646: };
647:
648: public String[] getRecommendedTypes() {
649: return TYPES;
650: }
651:
652: public String[] getPrivilegedTemplates() {
653: return PRIVILEGED_NAMES;
654: }
655: }
656:
657: public IcanproProjectProperties getProjectProperties() {
658: return new IcanproProjectProperties(this , helper, refHelper,
659: BpelproProjectType.PROJECT_CONFIGURATION_NAMESPACE);
660: }
661:
662: // vlv
663: private static class CatalogListener implements FileChangeListener {
664: public CatalogListener(FileObject project,
665: CatalogWriteModel catalog) {
666: //System.out.println();
667: //System.out.println();
668: //System.out.println("NEW CATALOG LISTENER " + project);
669: myCatalog = catalog;
670: myProject = project;
671: myEntries = null;
672: // vlv # 111020
673: updateEntries();
674: }
675:
676: public void fileChanged(FileEvent event) {
677: updateEntries();
678: }
679:
680: public void fileAttributeChanged(FileAttributeEvent event) {
681: }
682:
683: public void fileDataCreated(FileEvent event) {
684: }
685:
686: public void fileDeleted(FileEvent event) {
687: }
688:
689: public void fileFolderCreated(FileEvent event) {
690: }
691:
692: public void fileRenamed(FileRenameEvent event) {
693: }
694:
695: private void updateEntries() {
696: removeEntries();
697:
698: myEntries = new HashMap<FileObject, FileListener>();
699: Collection<CatalogEntry> entries = myCatalog
700: .getCatalogEntries();
701: //System.out.println();
702: //System.out.println();
703: //System.out.println("UPDATE CATALOG");
704:
705: for (CatalogEntry entry : entries) {
706: //System.out.println("see");
707: String name = getFileName(entry.getSource());
708: //System.out.println(" name: " + name);
709: //System.out.println(" file: " + new File(name));
710: FileObject source = FileUtil.toFileObject(FileUtil
711: .normalizeFile(new File(name)));
712:
713: if (source == null) {
714: continue;
715: }
716: //System.out.println(" source: " + source.getNameExt());
717: FileObject target = myProject.getFileObject(entry
718: .getTarget());
719:
720: if (target == null) {
721: continue;
722: }
723: //System.out.println(" target: " + target.getNameExt());
724: FileListener listener = new FileListener(target);
725: source.addFileChangeListener(listener);
726:
727: myEntries.put(source, listener);
728: }
729: }
730:
731: private void removeEntries() {
732: if (myEntries == null) {
733: return;
734: }
735: //System.out.println();
736: //System.out.println();
737: //System.out.println("CLEAR CATALOG");
738: Set<FileObject> files = myEntries.keySet();
739:
740: for (FileObject file : files) {
741: file.removeFileChangeListener(myEntries.get(file));
742: //System.out.println(" file: " + file.getNameExt());
743: }
744: myEntries.clear();
745: }
746:
747: private String getFileName(String file) {
748: file = file.replaceAll("%20", " ");
749:
750: if (file.startsWith("file:")) { // NOI18N
751: file = file.substring(5);
752: }
753: return file.replace("\\", "/"); // NOI18N
754: }
755:
756: private FileObject myProject;
757: private CatalogWriteModel myCatalog;
758: private HashMap<FileObject, FileListener> myEntries;
759: }
760:
761: // vlv
762: private static class FileListener implements FileChangeListener {
763: public FileListener(FileObject target) {
764: myTarget = target;
765: myIsValid = true;
766: }
767:
768: public void fileChanged(FileEvent event) {
769: FileObject source = event.getFile();
770: //System.out.println();
771: //System.out.println();
772: //System.out.println("FILE CHANGED: " + myIsValid + " " + myTarget.isValid() + " " + source.getNameExt());
773: //System.out.println();
774: //System.out.println();
775: if (!myIsValid) {
776: return;
777: }
778: if (!myTarget.isValid()) {
779: return;
780: }
781: InputStream input = null;
782: OutputStream output = null;
783: FileLock lock = null;
784:
785: try {
786: input = source.getInputStream();
787: lock = myTarget.lock();
788: output = myTarget.getOutputStream(lock);
789: FileUtil.copy(input, output);
790: } catch (FileNotFoundException e) {
791: // e.printStackTrace();
792: } catch (IOException e) {
793: // e.printStackTrace();
794: } finally {
795: if (lock != null) {
796: lock.releaseLock();
797: }
798: try {
799: if (output != null) {
800: output.close();
801: }
802: if (input != null) {
803: input.close();
804: }
805: } catch (IOException e) {
806: // e.printStackTrace();
807: }
808: }
809: }
810:
811: public void fileAttributeChanged(FileAttributeEvent event) {
812: }
813:
814: public void fileDataCreated(FileEvent event) {
815: }
816:
817: public void fileDeleted(FileEvent event) {
818: myIsValid = false;
819: }
820:
821: public void fileFolderCreated(FileEvent event) {
822: }
823:
824: public void fileRenamed(FileRenameEvent event) {
825: myIsValid = false;
826: }
827:
828: private boolean myIsValid;
829: private FileObject myTarget;
830: }
831: }
|