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-2006 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.apisupport.project.metainf;
043:
044: import java.io.IOException;
045: import java.io.InputStream;
046: import java.util.ArrayList;
047: import java.util.Iterator;
048: import java.util.List;
049: import java.util.Set;
050: import java.util.TreeMap;
051: import javax.swing.Action;
052: import org.netbeans.api.project.Project;
053: import org.netbeans.api.project.ProjectManager;
054: import org.netbeans.modules.apisupport.project.Util;
055: import org.netbeans.modules.apisupport.project.spi.NbModuleProvider;
056: import org.openide.DialogDisplayer;
057: import org.openide.ErrorManager;
058: import org.openide.NotifyDescriptor;
059: import org.openide.actions.DeleteAction;
060: import org.openide.filesystems.FileChangeListener;
061: import org.openide.filesystems.FileObject;
062: import org.openide.nodes.AbstractNode;
063: import org.openide.nodes.Children;
064: import org.openide.nodes.Node;
065: import org.openide.util.NbBundle;
066: import org.openide.util.RequestProcessor;
067:
068: /**
069: * Wraps the META-INF/services node in Important Files node
070: * @author pzajac
071: */
072: public final class ServiceNodeHandler {
073: private static final String KEY_WAIT = "wait"; // NOI18N
074:
075: private static final String THIS_SERVICES = NbBundle.getMessage(
076: ServiceNodeHandler.class, "LBL_this_services");
077: private static final String THIS_SERVICES_IN_CONTEXT = NbBundle
078: .getMessage(ServiceNodeHandler.class,
079: "LBL_this_services_in_context");
080: static final String ROOT_NODE_NAME = NbBundle.getMessage(
081: ServiceNodeHandler.class, "LBL_META_INF_services");
082: // All services in platform
083: TreeMap<String, List<Service>> /* service class -> List of classes */allServicesMap;
084: // services in module
085: TreeMap<String, List<Service>>/* service class -> List of classes */moduleServiceMap;
086:
087: int prevAllServicesCount = -1;
088: int prevModuleServicesCount = -1;
089:
090: final Project project;
091: final NbModuleProvider info;
092: List<Service> moduleServices;
093:
094: /** services in this module
095: */
096: ServiceRootChildren moduleChild;
097: /** services in context
098: */
099: ServiceRootChildren allInContextChild;
100: boolean registeredListener;
101: /** holds reference to META-INF/services folder
102: */
103: private FileObject metaInfServicesFo;
104: /** cached codebase name
105: */
106: private String codeNameBase;
107:
108: /** Children for services list
109: */
110: class ServiceRootChildren extends Children.Keys<String> {
111: boolean fullyComputed = false;
112: /** show services of this project or platfrom
113: */
114: private final boolean bProjectServices;
115:
116: ServiceRootChildren(boolean bProjectServices) {
117: this .bProjectServices = bProjectServices;
118: }
119:
120: protected Node[] createNodes(String key) {
121: // synchronize access to allServicesMap and moduleServices
122: if (key.equals(KEY_WAIT)) {
123: return new Node[] { new AbstractNode(Children.LEAF) {
124: @Override
125: public String getName() {
126: return KEY_WAIT;
127: }
128:
129: @Override
130: public String getDisplayName() {
131: return NbBundle.getMessage(
132: ServiceNodeHandler.class,
133: "LBL_ServiceNode_please_wait");
134: }
135:
136: @Override
137: public Action[] getActions(boolean context) {
138: return new Action[0];
139: }
140: } };
141: } else {
142: Node parent = getNode();
143: String parentName = parent.getName();
144: boolean isThisModule = parentName.equals(THIS_SERVICES);
145: ServiceNode node = new ServiceNode(key, isThisModule);
146: return new Node[] { node };
147: }
148:
149: }
150:
151: @Override
152: protected void addNotify() {
153: SUtil.log(SUtil.LOG_SERVICE_NODE_HANDLER_ADD_NOTIFY);
154: super .addNotify();
155: if (fullyComputed) {
156: if (bProjectServices) {
157: // only services from this project
158: prevModuleServicesCount = moduleServiceMap.keySet()
159: .size();
160: SUtil.log(SUtil.LOG_SET_KEYS);
161: setKeys(moduleServiceMap.keySet());
162: } else {
163: prevAllServicesCount = allServicesMap.keySet()
164: .size();
165: setKeys(allServicesMap.keySet());
166: }
167: } else {
168: SUtil.log(SUtil.LOG_COMPUTE_KEYS);
169: setKeys(new String[] { KEY_WAIT });
170: RequestProcessor.getDefault().post(new Runnable() {
171: public void run() {
172: try {
173: Set<String> keys = null;
174: // synchronize access to TreeMaps
175: // categorize services
176: synchronized (ServiceNodeHandler.this ) {
177: if (moduleServiceMap == null) {
178: moduleServiceMap = new TreeMap<String, List<Service>>();
179: moduleServices = Service
180: .getOnlyProjectServices(project);
181: sortServices(moduleServiceMap,
182: moduleServices);
183: }
184: if (bProjectServices) {
185: // only services from this project
186: keys = moduleServiceMap.keySet();
187: prevModuleServicesCount = moduleServiceMap
188: .keySet().size();
189: } else {
190: if (allServicesMap == null) {
191: allServicesMap = new TreeMap<String, List<Service>>();
192: List<Service> services = ServiceViewUpdater
193: .getAllServices(ServiceNodeHandler.this );
194: if (services != null) {
195: assert moduleServiceMap != null;
196: sortServices(
197: allServicesMap,
198: services);
199: }
200: }
201: prevAllServicesCount = allServicesMap
202: .keySet().size();
203: keys = allServicesMap.keySet();
204: if (!keys.isEmpty()) {
205: SUtil.log(keys.iterator()
206: .next().toString());
207: }
208: }
209:
210: }
211: setKeys(keys);
212: synchronized (ServiceNodeHandler.this ) {
213: // tell the test that it is initialized
214: fullyComputed = true;
215: SUtil.log(SUtil.LOG_END_COMPUTE_KEYS);
216: }
217: } catch (IOException e) {
218: Util.err.notify(ErrorManager.INFORMATIONAL,
219: e);
220: }
221: } // run
222:
223: private void sortServices(
224: final TreeMap<String, List<Service>> map,
225: final List<Service> services) {
226: // sortServices(map,services);
227: for (Service service : services) {
228: assert map != null;
229: List<Service> theSameServices = map
230: .get(service.getFileName());
231: if (theSameServices == null) {
232: theSameServices = new ArrayList<Service>();
233: map.put(service.getFileName(),
234: theSameServices);
235: }
236: theSameServices.add(service);
237: }
238: }
239: }); // runnable
240: } // else
241: }
242:
243: void refreshKeys() {
244: if (bProjectServices) {
245: setKeys(moduleServiceMap.keySet());
246: prevModuleServicesCount = moduleServiceMap.size();
247: } else {
248: setKeys(allServicesMap.keySet());
249: prevAllServicesCount = allServicesMap.size();
250: }
251: }
252:
253: public void updateNode(String keyName) {
254: for (Node _n : getNodes()) {
255: ServiceNode n = (ServiceNode) _n;
256: if (n.getName().equals(keyName)) {
257: n.refreshName();
258: ((ServiceNodeChildren) n.getChildren())
259: .nodesChanged();
260: }
261: }
262: }
263:
264: @Override
265: protected void removeNotify() {
266: setKeys(new String[0]);
267: super .removeNotify();
268: }
269:
270: }
271:
272: class ServiceClassKey {
273: String name;
274: boolean bRemoved;
275:
276: ServiceClassKey(String name, boolean bRemoved) {
277: this .name = name;
278: this .bRemoved = bRemoved;
279: }
280:
281: @Override
282: public int hashCode() {
283: return name.hashCode();
284: }
285:
286: @Override
287: public boolean equals(Object obj) {
288: return (obj instanceof ServiceClassKey)
289: && ((ServiceClassKey) obj).name.equals(name);
290: }
291:
292: }
293:
294: class ServiceNodeChildren extends Children.Keys<ServiceClassKey> {
295: private boolean isThisModule;
296: /** className -> ServiceClassKey
297: */
298: private TreeMap<String, ServiceClassKey> keys;
299: boolean initialized = true;
300:
301: ServiceNodeChildren(boolean isThisModule) {
302: this .isThisModule = isThisModule;
303: // setKeys(new Object[]{KEY_WAIT});
304: }
305:
306: private TreeMap<String, ServiceClassKey> getKeysMap() {
307: if (keys == null) {
308: keys = new TreeMap<String, ServiceClassKey>();
309: }
310: return keys;
311: }
312:
313: private ServiceClassKey addKey(ServiceClassKey key,
314: TreeMap<String, ServiceClassKey> newKeyMap) {
315: TreeMap<String, ServiceClassKey> ks = getKeysMap();
316: ServiceClassKey oldKey = ks.get(key.name);
317: if (oldKey == null) {
318: oldKey = key;
319: } else if (oldKey.bRemoved != key.bRemoved) {
320: oldKey.bRemoved = key.bRemoved;
321: refreshKey(oldKey);
322: }
323: newKeyMap.put(key.name, oldKey);
324: return oldKey;
325: }
326:
327: @Override
328: protected void addNotify() {
329: ServiceNode serviceNode = (ServiceNode) getNode();
330: isThisModule = serviceNode.isThisModule();
331: List<Service> servicesGroup = ((isThisModule) ? moduleServiceMap
332: .get(serviceNode.getName())
333: : allServicesMap.get(serviceNode.getName()));
334:
335: List<String> classes = new ArrayList<String>();
336: List<String> maskedClasses = new ArrayList<String>();
337:
338: TreeMap<String, ServiceClassKey> newKeyMap = new TreeMap<String, ServiceClassKey>();
339: // creates two groups - classes and masked class
340: //
341: for (Service service : servicesGroup) {
342: for (String name : service.getClasses()) {
343: if (name.charAt(0) == '-') {
344: maskedClasses.add(name);
345: } else {
346: classes.add(name);
347: }
348: }
349: }
350:
351: // create nodes from classes
352: //
353: for (String name : classes) {
354: ServiceClassKey key = new ServiceClassKey(name, false);
355: if (!isThisModule) {
356: String filteredName = '-' + name;
357: // register class like masked
358: for (String masked : maskedClasses) {
359: if (masked.equals(filteredName)) {
360: key.bRemoved = true;
361: }
362: }
363: }
364: key = addKey(key, newKeyMap);
365:
366: }
367: // show element which masks services in this module view
368: //
369: if (isThisModule) {
370: for (String masked : maskedClasses) {
371: addKey(new ServiceClassKey(masked, false),
372: newKeyMap);
373: }
374: }
375: this .keys = newKeyMap;
376: setKeys(getKeysMap().values());
377: initialized = true;
378: }
379:
380: protected Node[] createNodes(ServiceClassKey key) {
381: ServiceClassKey classKey = key;
382: ServiceClassNode node = new ServiceClassNode(classKey.name,
383: classKey.bRemoved);
384: return new Node[] { node };
385: }
386:
387: synchronized void nodesChanged() {
388: if (initialized) {
389: addNotify();
390: }
391:
392: }
393:
394: }
395:
396: /*** the service super class node
397: */
398: public final class ServiceNode extends AbstractNode {
399: ServiceNode(String name, boolean isThisModule) {
400: super (new ServiceNodeChildren(isThisModule));
401: setName(name);
402: setIconBaseWithExtension("org/netbeans/modules/apisupport/project/metainf/interface.png");
403: }
404:
405: public void updateChildren() {
406: ((ServiceNodeChildren) getChildren()).nodesChanged();
407: fireDisplayNameChange(null, null);
408: }
409:
410: boolean isThisModule() {
411: return (getParentNode() == null) ? false : getParentNode()
412: .getName().equals(THIS_SERVICES);
413: }
414:
415: @Override
416: public String getHtmlDisplayName() {
417: List<Service> services = moduleServiceMap.get(getName());
418: return (services != null && !isThisModule()) ? "<b>"
419: + getName() + "</b>" : getName(); //NOI18N
420: }
421:
422: @Override
423: public Action[] getActions(boolean context) {
424: return new Action[] { AddService.getInstance() };
425: }
426:
427: /** create new service (also creates new file)
428: */
429: void addService(String serviceName, String classServiceName) {
430: List<Service> services = allServicesMap.get(serviceName);
431: boolean exists = false;
432: for (Service service : services) {
433: for (String className : service.getClasses()) {
434: if (classServiceName.equals(className)) {
435: // already exist
436: exists = true;
437: NotifyDescriptor.Message msgDesc = new NotifyDescriptor.Message(
438: NbBundle.getMessage(
439: ServiceNodeHandler.class,
440: "MSG_ServiceExist", className));
441: DialogDisplayer.getDefault().notify(msgDesc);
442: }
443: }
444: }
445: if (!exists) {
446: services = moduleServiceMap.get(serviceName);
447: Service service = null;
448: if (services != null && services.size() > 0) {
449: service = services.get(0);
450: } else {
451: service = new Service(getInfo().getCodeNameBase(),
452: serviceName, new ArrayList<String>());
453: }
454: service.getClasses().add(classServiceName);
455: service.write(project);
456: }
457: }
458:
459: void refreshName() {
460: fireDisplayNameChange(null, null);
461: }
462:
463: Project getProject() {
464: return project;
465: }
466:
467: NbModuleProvider getInfo() {
468: return project.getLookup().lookup(NbModuleProvider.class);
469: }
470:
471: }
472:
473: /** leaf of services - a node for a class
474: */
475: public final class ServiceClassNode extends AbstractNode {
476: /** is the classs masked in other module?
477: */
478: boolean bRemoved;
479:
480: ServiceClassNode(String className, boolean bRemoved) {
481: super (Children.LEAF);
482: setName(className);
483: this .bRemoved = bRemoved;
484: if (className.startsWith("-")) { // NOI18N
485: setIconBaseWithExtension("org/netbeans/modules/apisupport/project/metainf/noinstance.png");
486: } else {
487: setIconBaseWithExtension("org/netbeans/modules/apisupport/project/metainf/instance.png");
488: }
489: }
490:
491: Service getService() {
492: // The parent node can be null
493: if (getParentNode() != null) {
494: List<Service> services = allServicesMap
495: .get(getParentNode().getName());
496: String name = getName();
497: if (services != null) {
498: for (Service service : services) {
499: for (String n : service.getClasses()) {
500: if (name.equals(n)) {
501: return service;
502: }
503: }
504: }
505: }
506: }
507: return null;
508: }
509:
510: @Override
511: public Action[] getActions(boolean context) {
512: return new Action[] { DeleteAction.get(DeleteAction.class) };
513: }
514:
515: @Override
516: public String getHtmlDisplayName() {
517: List<Service> services = moduleServiceMap
518: .get(getParentNode().getName());
519: String name = getName();
520: boolean bFound = false;
521: if (services != null) {
522: for (Service service : services) {
523: for (String n : service.getClasses()) {
524: if (name.equals(n)) {
525: bFound = true;
526: break;
527: }
528: }
529: }
530: }
531: String dispName = (bFound && !getParentNode()
532: .getParentNode().getName().equals(THIS_SERVICES)) ? "<b>"
533: + name + "</b>"
534: : name; //NOI18N
535: if (bRemoved) {
536: dispName = "<s>" + dispName + "</s>"; //NOI18N
537: }
538: return dispName;
539: }
540:
541: /* XXX #126577: just throws NPE if you try
542: @Override
543: public boolean canDestroy() {
544: return true;
545: }
546: */
547: @Override
548: public boolean canCopy() {
549: return false;
550: }
551:
552: @Override
553: public void destroy() throws IOException {
554: Service service = getService();
555: // exists the service?
556: if (service != null) {
557: Service moduleService = null;
558: List<Service> moduleServices = moduleServiceMap
559: .get(service.getFileName());
560: if (moduleServices == null
561: || moduleServices.size() == 0) {
562: // create service in this modulu if the service doesn't exist
563: List<String> classes = new ArrayList<String>();
564: moduleService = new Service(service.getCodebase(),
565: service.getFileName(), classes);
566: } else {
567: moduleService = moduleServices.get(0);
568: }
569: moduleService.removeClass(getName(), project);
570: }
571: }
572: }
573:
574: public ServiceNodeHandler(Project project, NbModuleProvider provider) {
575: this .project = project;
576: this .info = provider;
577: if (!registeredListener) {
578: // #87269 deadlock when file is modified externally on project initialization
579: // for example cvs update can cause it
580: ProjectManager.mutex().postWriteRequest(new Runnable() {
581: public void run() {
582: registerFileObjectListener();
583: }
584: });
585: }
586:
587: }
588:
589: /** creates root node which will be placed into important files node
590: */
591: public Node createServiceRootNode() {
592: return new ServiceRootNode();
593: }
594:
595: class ServiceRootNode extends AbstractNode {
596: ServiceRootNode() {
597: super (new Children.Array());
598: setDisplayName(ROOT_NODE_NAME);
599: setName(ROOT_NODE_NAME);
600: Children.Array childs = (Children.Array) getChildren();
601: childs.add(new Node[] { createServiceFolderNode(true),
602: createServiceFolderNode(false) });
603: setIconBaseWithExtension("org/netbeans/modules/apisupport/project/metainf/services.png");
604: }
605:
606: ServiceNodeHandler getNodeHandler() {
607: return ServiceNodeHandler.this ;
608: }
609:
610: @Override
611: public Action[] getActions(boolean context) {
612: return new Action[0];
613: }
614: }
615:
616: static class ServiceFolderNode extends AbstractNode {
617: ServiceFolderNode(Children children) {
618: super (children);
619: }
620:
621: @Override
622: public Action[] getActions(boolean context) {
623: return new Action[0];
624: }
625: }
626:
627: private Node createServiceFolderNode(boolean bProjectServices) {
628: ServiceRootChildren children = new ServiceRootChildren(
629: bProjectServices);
630: AbstractNode node = new ServiceFolderNode(children);
631: if (bProjectServices) {
632: node.setDisplayName(THIS_SERVICES);
633: node.setName(THIS_SERVICES);
634: node
635: .setIconBaseWithExtension("org/netbeans/modules/apisupport/project/metainf/export.png");
636: moduleChild = children;
637: } else {
638: node.setDisplayName(THIS_SERVICES_IN_CONTEXT);
639: node.setName(THIS_SERVICES_IN_CONTEXT);
640: node
641: .setIconBaseWithExtension("org/netbeans/modules/apisupport/project/metainf/services.png");
642: allInContextChild = children;
643: }
644: return node;
645: }
646:
647: ////////////////////////////////////////////////////////////////
648: // Filechange listener
649: /////////////////////////////////////////////////////
650:
651: /** listen on :
652: * META-INF/service | META-INF | project/src
653: */
654: public void registerFileObjectListener() {
655: FileObject srcDir = project.getProjectDirectory()
656: .getFileObject(info.getResourceDirectoryPath(false));
657:
658: // srcDir is sometimes null, is it bug?
659: if (srcDir != null) {
660: if (!registeredListener) {
661: registeredListener = true;
662: FileObject fo = srcDir.getFileObject("META-INF"); //NOI18N
663: FileChangeListener listener = ServicesFileListener
664: .getInstance();
665: if (fo != null) {
666: fo.removeFileChangeListener(listener);
667: fo.addFileChangeListener(listener);
668: metaInfServicesFo = fo;
669: fo = fo.getFileObject("services"); //NOI18N
670: if (fo != null) {
671: fo.removeFileChangeListener(listener);
672: fo.addFileChangeListener(listener);
673: metaInfServicesFo = fo;
674: }
675: } else {
676: srcDir.removeFileChangeListener(listener);
677: srcDir.addFileChangeListener(listener);
678: metaInfServicesFo = srcDir;
679: }
680: }
681: } else {
682: // Error - logging
683: ErrorManager em = ErrorManager.getDefault();
684: em.log(" project.getSourceDirectory() = null");
685: em.log("codenamebase = " + info.getCodeNameBase());
686: em.log("projectroot = "
687: + project.getProjectDirectory().getPath());
688: }
689: }
690:
691: void updateFile(FileObject fo) {
692: try {
693: if (fo.getParent() == SUtil.getServicesFolder(project,
694: false)) {
695: InputStream is = fo.getInputStream();
696: Service service = Service.createService(info
697: .getCodeNameBase(), fo.getNameExt(), is);
698: is.close();
699: ServiceViewUpdater.serviceUpdated(service, this );
700: // merge or add service
701: }
702: } catch (IOException ioe) {
703: ErrorManager.getDefault().notify(ioe);
704: }
705:
706: }
707:
708: /** remove nodes ...
709: */
710: void removeFile(FileObject fileObject) throws IOException {
711: if (fileObject.getParent() == SUtil.getServicesFolder(project,
712: false)) {
713: String name = fileObject.getNameExt();
714: if (moduleServiceMap != null) {
715: Service service = null;
716: synchronized (this ) {
717: List services = (List) moduleServiceMap.get(name);
718: if (services != null && services.size() > 0) {
719: service = (Service) services.get(0);
720: }
721: moduleServiceMap.remove(name);
722:
723: if (allServicesMap != null) {
724: services = (List) allServicesMap.get(name);
725: if (services != null) {
726: services.remove(service);
727:
728: if (services.isEmpty()) {
729: allServicesMap.remove(name);
730: }
731: }
732: }
733: }
734: updateNode(service);
735: }
736: }
737: }
738:
739: /** update node of services list
740: * - add node
741: * - modify list of classes
742: * - remove node
743: */
744: private void updateNode(Service service) {
745: String name = (service == null) ? null : service.getFileName();
746: if (moduleChild != null && moduleChild.fullyComputed
747: && moduleServiceMap != null) {
748: if (prevModuleServicesCount == moduleServiceMap.size()
749: && name != null) {
750: // update only key
751: moduleChild.updateNode(name);
752: } else {
753: moduleChild.refreshKeys();
754: prevModuleServicesCount = moduleServiceMap.size();
755: }
756: }
757: if (allInContextChild != null
758: && allInContextChild.fullyComputed
759: && allServicesMap != null) {
760: if (prevAllServicesCount == allServicesMap.size()
761: && name != null) {
762: allInContextChild.updateNode(name);
763: } else {
764: allInContextChild.refreshKeys();
765: prevAllServicesCount = allServicesMap.size();
766: }
767: }
768: }
769:
770: @Override
771: public int hashCode() {
772: return getKeyName().hashCode();
773: }
774:
775: @Override
776: public boolean equals(Object obj) {
777: return obj instanceof ServiceNodeHandler
778: && getKeyName().equals(
779: ((ServiceNodeHandler) obj).getKeyName());
780: }
781:
782: void updateService(Service service) {
783: // throw new UnsupportedOperationException("Not yet implemented");
784: synchronized (this ) {
785: if (moduleServiceMap != null) {
786: List<Service> services = moduleServiceMap.get(service
787: .getFileName());
788: if (service.getCodebase()
789: .equals(info.getCodeNameBase())) {
790: if (services != null && services.size() > 0) {
791: services.remove(0);
792: } else {
793: services = new ArrayList<Service>();
794: moduleServiceMap.put(service.getFileName(),
795: services);
796: }
797: services.add(service);
798: }
799:
800: if (allServicesMap != null) {
801: services = allServicesMap
802: .get(service.getFileName());
803: if (services != null && services.size() > 0) {
804: // find service
805: Iterator<Service> sIt = services.iterator();
806: while (sIt.hasNext()) {
807: if (sIt.next().getCodebase().equals(
808: service.getCodebase())) {
809: sIt.remove();
810: break;
811: }
812: }
813: } else {
814: services = new ArrayList<Service>();
815: allServicesMap.put(service.getFileName(),
816: services);
817: }
818: services.add(service);
819: }
820: updateNode(service);
821: }
822: }
823: }
824:
825: Project getProject() {
826: return project;
827: }
828:
829: private String getKeyName() {
830: // #103798 important files node hashCode problems.
831: // probably on cnb change
832: if (codeNameBase == null) {
833: codeNameBase = info.getCodeNameBase();
834: }
835: // cnb will be null if project is deleted
836: if (codeNameBase == null) {
837: codeNameBase = "unknown"; // NOI18N
838: }
839: return codeNameBase;
840: }
841: }
|