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.bpel.properties;
021:
022: import java.awt.Component;
023: import java.awt.Container;
024: import java.awt.Dialog;
025: import java.util.ArrayList;
026: import java.util.List;
027: import org.netbeans.modules.bpel.properties.editors.FormBundle;
028: import org.netbeans.modules.soa.ui.form.CustomNodeEditor;
029: import org.netbeans.modules.soa.ui.form.valid.SoaDialogDisplayer;
030: import org.netbeans.modules.bpel.editors.api.ui.valid.NodeEditorDescriptor;
031: import org.netbeans.modules.bpel.nodes.BpelNode;
032: import org.netbeans.modules.bpel.nodes.ContainerBpelNode;
033: import org.netbeans.modules.soa.ui.SoaUiUtil;
034: import org.openide.nodes.Node;
035: import org.openide.util.NbBundle;
036:
037: /**
038: *
039: * @author nk160297
040: */
041: public class NodeUtils {
042:
043: /**
044: * Shows a custom editor for the specified Node.
045: * @returns TRUE if dialog was submited with OK buppon
046: */
047: public static boolean showNodeCustomEditor(Node node,
048: CustomNodeEditor.EditingMode editingMode) {
049: if (node == null) {
050: return false;
051: }
052: //
053: Component c = null;
054: if (node instanceof BpelNode) {
055: c = ((BpelNode) node).getCustomizer(editingMode);
056: } else {
057: c = node.getCustomizer();
058: }
059: //
060: if (c == null) {
061: return false;
062: }
063: //
064: String title;
065: if (CustomNodeEditor.EditingMode.CREATE_NEW_INSTANCE == editingMode
066: && node instanceof BpelNode) {
067: String nodeTypeName = ((BpelNode) node).getNodeType()
068: .getDisplayName();
069: String createNew = NbBundle.getMessage(FormBundle.class,
070: "LBL_Create_New"); // NOI18N
071: title = createNew + " " + nodeTypeName; // NOI18N
072: } else {
073: String nodeName = node.getDisplayName();
074: String propEditor = NbBundle.getMessage(FormBundle.class,
075: "LBL_Property_Editor"); // NOI18N
076: if (nodeName != null && nodeName.length() > 0) {
077: title = nodeName + " - " + propEditor; // NOI18N
078: } else {
079: title = propEditor;
080: }
081: }
082: //
083: if (c instanceof CustomNodeEditor) {
084: CustomNodeEditor editor = (CustomNodeEditor) c;
085: NodeEditorDescriptor descriptor = new NodeEditorDescriptor(
086: editor, title);
087: Dialog dialog = SoaDialogDisplayer.getDefault()
088: .createDialog(descriptor);
089: SoaUiUtil.setInitialFocusComponentFor((Container) c);
090: dialog.setVisible(true);
091:
092: return descriptor.isOkHasPressed();
093: }
094: return false;
095: }
096:
097: public static List<Node> findNodes(Node sourceNode,
098: SearchVisitor visitor, int maxDepth) {
099: List<Node> result = new ArrayList<Node>();
100: fillNodesList(result, sourceNode, visitor, maxDepth, false);
101: return result;
102: }
103:
104: /**
105: * An auxiliary method is intended to help seach nodes recursively.
106: */
107: private static void fillNodesList(List<Node> nodesList,
108: Node sourceNode, SearchVisitor visitor, int maxDepth,
109: boolean lookDeeperIfFound) {
110: //
111: if (visitor.accept(sourceNode)) {
112: nodesList.add(sourceNode);
113: if (!lookDeeperIfFound) {
114: return;
115: }
116: }
117: //
118: if (maxDepth == 0) {
119: return;
120: }
121: //
122: if (visitor.drillDeeper(sourceNode)) {
123: Node[] nodes = sourceNode.getChildren().getNodes();
124: maxDepth--;
125: for (Node node : nodes) {
126: fillNodesList(nodesList, node, visitor, maxDepth,
127: lookDeeperIfFound);
128: }
129: }
130: return;
131: }
132:
133: /**
134: * An auxiliary method is intended to help seach nodes recursively.
135: * The sourceNode parameter specifies the search root.
136: * <p>
137: * The maxDepth parameter specifies the maximum depth do
138: * which the recursive algorithm can go.
139: * <p>
140: * If it equals to -1, then infinite depth is emplied.
141: * <p>
142: * if it equals to 0 than it means that it only necessary to check
143: * if the sourceNode satisfies to the searching conditions.
144: * <p>
145: * if it equals to 1 than it means that searching is requested
146: * only among direct children of the source node.
147: */
148: public static Node findFirstNode(Node sourceNode,
149: SearchVisitor visitor, int maxDepth) {
150: //
151: if (visitor.accept(sourceNode)) {
152: return sourceNode;
153: }
154: //
155: if (maxDepth == 0) {
156: return null;
157: }
158: //
159: if (visitor.drillDeeper(sourceNode)) {
160: Node[] nodes = sourceNode.getChildren().getNodes();
161: maxDepth--;
162: for (Node node : nodes) {
163: Node resultNode = findFirstNode(node, visitor, maxDepth);
164: if (resultNode != null) {
165: return resultNode;
166: }
167: }
168: }
169: return null;
170: }
171:
172: public interface SearchVisitor {
173: /**
174: * Indicates if the node satisfies the search conditions
175: */
176: boolean accept(Node node);
177:
178: /**
179: * Indicates if it necessary to search diiper than the specified node.
180: */
181: boolean drillDeeper(Node node);
182: }
183:
184: //--------------------------------------------------------------
185: // Special implementations
186: //--------------------------------------------------------------
187:
188: /**
189: * Look for the first Node in the Nodes' hierarchy recursively.
190: * <p>
191: * If it equals to -1, then infinite depth is emplied.
192: * <p>
193: * if it equals to 0 than it means that it only necessary to check
194: * if the sourceNode satisfies to the searching conditions.
195: * <p>
196: * if it equals to 1 than it means that searching is requested
197: * only among direct children of the source node.
198: * <p>
199: * CAUTION! This method do simple iteration over th� hierarchy.
200: * So it can take a lot of time depending on the data structure
201: * if the maxDepth restriction isn't specified!
202: */
203: public static <S> BpelNode<S> findFirstNode(final S requiredObj,
204: Node sourceNode, int maxDepth) {
205: //
206: NodeUtils.SearchVisitor visitor = new NodeUtils.SearchVisitor() {
207: public boolean accept(Node node) {
208: if (node instanceof ContainerBpelNode) {
209: Object container = ((ContainerBpelNode) node)
210: .getContainerReference();
211: if (requiredObj.equals(container)) {
212: return true;
213: }
214: } else if (node instanceof BpelNode) {
215: Object subject = ((BpelNode) node).getReference();
216: if (requiredObj.equals(subject)) {
217: return true;
218: }
219: }
220: //
221: return false;
222: }
223:
224: public boolean drillDeeper(Node node) {
225: return true;
226: }
227: };
228: //
229: Node resultNode = findFirstNode(sourceNode, visitor, maxDepth);
230: if (resultNode != null && resultNode instanceof BpelNode) {
231: return (BpelNode) resultNode;
232: } else {
233: return null;
234: }
235: }
236:
237: /**
238: * Look for the first Node in the Nodes' hierarchy recursively.
239: * <p>
240: * If it equals to -1, then infinite depth is emplied.
241: * <p>
242: * if it equals to 0 than it means that it only necessary to check
243: * if the sourceNode satisfies to the searching conditions.
244: * <p>
245: * if it equals to 1 than it means that searching is requested
246: * only among direct children of the source node.
247: * <p>
248: * If the requiredObj parameter is null then only the node class is
249: * taken into consideration.
250: * <p>
251: * CAUTION! This method do simple iteration over th� hierarchy.
252: * So it can take a lot of time depending on the data structure
253: * if the maxDepth restriction isn't specified!
254: */
255: public static <P extends BpelNode> P findFirstNode(
256: final Object requiredObj, final Class<P> requiredNodeClass,
257: Node sourceNode, int maxDepth) {
258: //
259: NodeUtils.SearchVisitor visitor = new NodeUtils.SearchVisitor() {
260: public boolean accept(Node node) {
261: if (requiredNodeClass.isAssignableFrom(node.getClass())) {
262: if (requiredObj == null) {
263: return true;
264: }
265: if (node instanceof ContainerBpelNode) {
266: Object container = ((ContainerBpelNode) node)
267: .getContainerReference();
268: if (requiredObj.equals(container)) {
269: return true;
270: }
271: } else if (node instanceof BpelNode) {
272: Object subject = ((BpelNode) node)
273: .getReference();
274: if (requiredObj.equals(subject)) {
275: return true;
276: }
277: }
278: }
279: //
280: return false;
281: }
282:
283: public boolean drillDeeper(Node node) {
284: return true;
285: }
286: };
287: //
288: Node resultNode = findFirstNode(sourceNode, visitor, maxDepth);
289: if (resultNode != null && resultNode instanceof BpelNode) {
290: return (P) resultNode;
291: } else {
292: return null;
293: }
294: }
295:
296: public static <P extends BpelNode> P findFirstNode(
297: Object requiredObj, Class<P> requiredNodeClass,
298: Node sourceNode) {
299: return findFirstNode(requiredObj, requiredNodeClass,
300: sourceNode, -1);
301: }
302:
303: public static <S> BpelNode<S> findFirstNode(S requiredObj,
304: Node sourceNode) {
305: return findFirstNode(requiredObj, sourceNode, -1);
306: }
307:
308: }
|