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.core;
020:
021: import java.awt.Image;
022: import java.awt.event.ActionEvent;
023: import java.io.IOException;
024: import java.util.LinkedList;
025: import java.util.List;
026: import java.util.concurrent.atomic.AtomicBoolean;
027: import java.util.concurrent.atomic.AtomicReference;
028:
029: import javax.swing.AbstractAction;
030: import javax.swing.Action;
031: import javax.xml.transform.Source;
032: import org.netbeans.modules.bpel.core.annotations.impl.AnnotationManagerProvider;
033:
034: import org.netbeans.modules.bpel.core.helper.impl.BusinessProcessHelperImpl;
035: import org.netbeans.modules.bpel.core.multiview.BpelMultiViewSupport;
036: import org.netbeans.modules.bpel.core.util.BadgedIconCache;
037: import org.netbeans.modules.bpel.core.util.BPELValidationController;
038: import org.netbeans.modules.bpel.model.api.BpelModel;
039: import org.netbeans.modules.xml.api.XmlFileEncodingQueryImpl;
040: import org.netbeans.spi.xml.cookies.CheckXMLSupport;
041: import org.netbeans.spi.xml.cookies.DataObjectAdapters;
042: import org.netbeans.spi.xml.cookies.TransformableSupport;
043: import org.openide.cookies.SaveCookie;
044: import org.openide.filesystems.FileObject;
045: import org.openide.loaders.DataNode;
046: import org.openide.loaders.DataObjectExistsException;
047: import org.openide.loaders.MultiDataObject;
048: import org.openide.loaders.MultiFileLoader;
049: import org.openide.nodes.Children;
050: import org.openide.nodes.CookieSet;
051: import org.openide.nodes.Node;
052: import org.openide.util.HelpCtx;
053: import org.openide.util.Lookup;
054: import org.openide.util.NbBundle;
055: import org.openide.util.lookup.AbstractLookup;
056: import org.openide.util.lookup.InstanceContent;
057: import org.openide.util.lookup.Lookups;
058: import org.openide.util.lookup.ProxyLookup;
059: import org.xml.sax.InputSource;
060:
061: /**
062: * @author ads
063: */
064: public class BPELDataObject extends MultiDataObject {
065:
066: private static final long serialVersionUID = 1L;
067:
068: private static final String ICON_BASE = "org/netbeans/modules/bpel/core/resources/bp_file.gif"; // NOI18N
069:
070: private static final String FILE_DESC = "LBL_FileNode_desc"; // NOI18N
071:
072: public BPELDataObject(final FileObject obj,
073: final MultiFileLoader loader)
074: throws DataObjectExistsException {
075: super (obj, loader);
076:
077: myEditorSupport = new BPELDataEditorSupport(this );
078:
079: CookieSet set = getCookieSet();
080: set.add(getEditorSupport());
081:
082: InputSource in = DataObjectAdapters.inputSource(this );
083: set.add(new CheckXMLSupport(in));
084: // add TransformableCookie
085: Source source = DataObjectAdapters.source(this );
086: set.add(new TransformableSupport(source));
087: //set.add(new ValidateXMLSupport(in));
088: set.add(new AnnotationManagerProvider(this ));
089: }
090:
091: public HelpCtx getHelpCtx() {
092: return new HelpCtx(BPELDataObject.class);
093: }
094:
095: @Override
096: public void setModified(boolean modified) {
097: super .setModified(modified);
098: if (modified) {
099: getCookieSet().add(getSaveCookie());
100: if (isLookupInit.get()) {
101: myServices.get().add(getSaveCookie());
102: }
103: } else {
104: getCookieSet().remove(getSaveCookie());
105: if (isLookupInit.get()) {
106: myServices.get().remove(getSaveCookie());
107: }
108: }
109: }
110:
111: public BPELDataEditorSupport getEditorSupport() {
112: return myEditorSupport;
113: }
114:
115: private SaveCookie getSaveCookie() {
116: return new SaveCookie() {
117:
118: public void save() throws IOException {
119: getEditorSupport().saveDocument();
120: }
121:
122: @Override
123: public int hashCode() {
124: return getClass().hashCode();
125: }
126:
127: @Override
128: public boolean equals(Object other) {
129: return other != null
130: && getClass().equals(other.getClass());
131: }
132: };
133: }
134:
135: public final Lookup getLookup() {
136: if (myLookup.get() == null) {
137:
138: Lookup lookup;
139: List<Lookup> list = new LinkedList<Lookup>();
140:
141: list.add(Lookups.fixed(new Object[] {
142: super .getLookup(),
143: this ,
144: // getEditorSupport() is needed for retrieving Editor Support.
145: // This lookup will be put into Design Nodes, so they will have the same lookup.
146: getEditorSupport(),
147: // Model is needed by all design. Design is used lookup for accessing to model.
148: //// getEditorSupport().getBpelModel(),
149: // Helper is also needed by design. It used in property editors.
150: new BusinessProcessHelperImpl(this ),
151: XmlFileEncodingQueryImpl.singleton()
152: // Add Validation Controller.
153: //// new BPELValidationController(getEditorSupport().getBpelModel())
154: }));
155:
156: list.add(getCookieSet().getLookup());// 125540
157:
158: // add lazy initialization
159: InstanceContent.Convertor<Class, Object> conv = new InstanceContent.Convertor<Class, Object>() {
160: private AtomicReference<BPELValidationController> valControllerRef = new AtomicReference<BPELValidationController>();
161:
162: public Object convert(Class obj) {
163: if (obj == BpelModel.class) {
164: return getEditorSupport().getBpelModel();
165: }
166:
167: if (obj == BPELValidationController.class) {
168: valControllerRef.compareAndSet(null,
169: new BPELValidationController(
170: getEditorSupport()
171: .getBpelModel()));
172: return valControllerRef.get();
173: }
174: return null;
175: }
176:
177: public Class type(Class obj) {
178: return obj;
179: }
180:
181: public String id(Class obj) {
182: return obj.toString();
183: }
184:
185: public String displayName(Class obj) {
186: return obj.getName();
187: }
188: };
189:
190: list.add(Lookups.fixed(new Class[] { BpelModel.class,
191: BPELValidationController.class }, conv));
192: //
193:
194: /*
195: * Services are used for push/pop SaveCookie in lookup. This allow to work
196: * "Save" action on diagram.
197: */
198: myServices.compareAndSet(null, new InstanceContent());
199: myServices.get().add(new Empty()); // FIX for #IZ78702
200: list.add(new AbstractLookup(myServices.get()));
201:
202: lookup = new ProxyLookup(list.toArray(new Lookup[list
203: .size()]));
204:
205: myLookup.compareAndSet(null, lookup);
206: isLookupInit.compareAndSet(false, true);
207: }
208: return myLookup.get();
209: }
210:
211: protected Node createNodeDelegate() {
212: return new BPELNode(this , getEditorSupport());
213: }
214:
215: private static class BPELNode extends DataNode {
216:
217: public BPELNode(BPELDataObject obj,
218: BPELDataEditorSupport support) {
219: super (obj, Children.LEAF);
220: myEditorSupport = support;
221:
222: /*
223: * recomendation from javadoc for createNodeDelegate() that
224: * getCookie(DataObject.class) for this class should return obj.
225: */
226: getCookieSet().add(obj);
227:
228: setIconBaseWithExtension(ICON_BASE);
229: setShortDescription(NbBundle.getMessage(getClass(),
230: FILE_DESC));
231: }
232:
233: public Action getPreferredAction() {
234: return new AbstractAction() {
235: private static final long serialVersionUID = 1L;
236:
237: public void actionPerformed(ActionEvent e) {
238: // Fix for #81066
239: if (myEditorSupport.getOpenedPanes() == null
240: || myEditorSupport.getOpenedPanes().length == 0) {
241: myEditorSupport.open();
242: BpelMultiViewSupport support = BpelMultiViewSupport
243: .getInstance();
244: support.requestViewOpen(myEditorSupport);
245: } else {
246: myEditorSupport.open();
247: }
248: }
249: };
250: }
251:
252: protected boolean isWarning() {
253: return false; // TODO - hook in to dataobject
254: }
255:
256: protected boolean isError() {
257: return false; // TODO - hook in to dataobject
258: }
259:
260: /**
261: * to pick up change in warn/error condition call fireIconChange()
262: */
263: public Image getIcon(int type) {
264: if (!isWarning() && !isError())
265: return super .getIcon(type);
266: else if (isError()) {
267: return BadgedIconCache
268: .getErrorIcon(super .getIcon(type));
269: } else {
270: return BadgedIconCache.getWarningIcon(super
271: .getIcon(type));
272: }
273: }
274:
275: public Image getOpenedIcon(int type) {
276: if (!isWarning() && !isError())
277: return super .getOpenedIcon(type);
278: else if (isError()) {
279: return BadgedIconCache.getErrorIcon(super
280: .getOpenedIcon(type));
281: } else {
282: return BadgedIconCache.getWarningIcon(super
283: .getOpenedIcon(type));
284: }
285: }
286:
287: public HelpCtx getHelpCtx() {
288: return new HelpCtx(BPELDataObject.class);
289: }
290:
291: private BPELDataEditorSupport myEditorSupport;
292: }
293:
294: private static class Empty {
295:
296: }
297:
298: private transient BPELDataEditorSupport myEditorSupport;
299: private transient AtomicReference<Lookup> myLookup = new AtomicReference<Lookup>();
300: private transient AtomicReference<InstanceContent> myServices = new AtomicReference<InstanceContent>();
301: private transient AtomicBoolean isLookupInit = new AtomicBoolean(
302: false);
303: }
|