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.xml.refactoring.spi;
043:
044: import java.awt.Color;
045: import java.awt.Image;
046: import java.beans.BeanInfo;
047: import java.io.IOException;
048: import java.util.Enumeration;
049: import java.util.Iterator;
050: import java.util.List;
051: import javax.swing.tree.TreeModel;
052: import org.netbeans.modules.refactoring.api.AbstractRefactoring;
053: import org.netbeans.modules.refactoring.spi.ui.UI;
054: import org.netbeans.modules.xml.nbprefuse.AnalysisConstants;
055: import org.netbeans.modules.xml.refactoring.CannotRefactorException;
056: import org.netbeans.modules.xml.refactoring.ui.ModelProvider;
057: import org.netbeans.modules.xml.refactoring.ui.RenameRefactoringUI;
058: import org.netbeans.modules.xml.refactoring.ui.ReferenceableProvider;
059: import org.netbeans.modules.xml.refactoring.ui.DeleteRefactoringUI;
060: import org.netbeans.modules.xml.refactoring.ui.FileRenameRefactoringUI;
061: import org.netbeans.modules.xml.refactoring.ui.views.WhereUsedView;
062: import org.netbeans.modules.xml.xam.Component;
063: import org.netbeans.modules.xml.xam.Model;
064: import org.netbeans.modules.xml.xam.Nameable;
065: import org.netbeans.modules.xml.xam.Named;
066: import org.netbeans.modules.xml.xam.NamedReferenceable;
067: import org.netbeans.modules.xml.xam.Referenceable;
068: import org.openide.DialogDisplayer;
069: import org.openide.ErrorManager;
070: import org.openide.NotifyDescriptor;
071: import org.openide.filesystems.FileObject;
072: import org.openide.filesystems.FileUtil;
073: import org.openide.loaders.DataObject;
074: import org.openide.loaders.DataObjectNotFoundException;
075: import org.openide.text.CloneableEditorSupport;
076: import org.openide.util.NbBundle;
077: import org.openide.windows.TopComponent;
078: import prefuse.Visualization;
079: import prefuse.data.Edge;
080: import prefuse.data.Graph;
081: import prefuse.data.Node;
082: import prefuse.data.expression.Predicate;
083: import prefuse.data.expression.parser.ExpressionParser;
084: import prefuse.util.ColorLib;
085: import prefuse.visual.EdgeItem;
086: import prefuse.visual.NodeItem;
087:
088: /**
089: *
090: * @author Jeri Lockhart
091: */
092: public abstract class AnalysisUtilities {
093:
094: /**
095: * Find the first CheckNode in the tree model that has the passed user object
096: * @param model the TreeModel
097: * @param object the user object
098: * @returns CheckNode the check node that contains the user object, or null
099: * if none is found
100: *
101: */
102: /* public static CheckNode findCheckNode(TreeModel model, Object userObject){
103: if (model == null || userObject == null){
104: return null;
105: }
106: CheckNode root = (CheckNode)model.getRoot();
107: if (root.getUserObject() == userObject){
108: return root;
109: }
110: return processChildren(root, userObject);
111:
112: }*/
113:
114: /* private static CheckNode processChildren(CheckNode node, Object userObject){
115: Enumeration en = node.children();
116: while (en.hasMoreElements()){
117: CheckNode child = (CheckNode)en.nextElement();
118: Object currUserObject = child.getUserObject();
119: if (currUserObject == userObject){
120: return child;
121: }
122: return processChildren(child, userObject);
123: }
124: return null;
125: }*/
126:
127: /**
128: * Returns a color palette of given size that cycles through
129: * the hues of the HSB (Hue/Saturation/Brightness) color space.
130: * @param size the size of the color palette
131: * @param s the saturation value to use
132: * @param b the brightness value to use
133: * @param huesToExclude null or an array of hues to exclude from palette
134: * @return the color palette
135: */
136: public static int[] getHSBPalette(int size, float s, float b,
137: AnalysisConstants.HSBHues[] huesToExclude) {
138: int[] cm = new int[size];
139: int igen = 0;
140: for (int i = 0; i < size; i++) {
141: float h = 0;
142: boolean goodHue = false;
143: while (goodHue == false) {
144: h = ((float) igen++) / (size);
145: if (huesToExclude != null) {
146: for (AnalysisConstants.HSBHues exH : huesToExclude) {
147: goodHue = !isInColorFamily(h, exH);
148: if (goodHue == false) {
149: break;
150: }
151: }
152: } else {
153: goodHue = true;
154: }
155: }
156: cm[i] = ColorLib.hsb(h, s, b);
157: }
158: return cm;
159: }
160:
161: private static boolean isInColorFamily(float h,
162: AnalysisConstants.HSBHues hue) {
163: if (hue == null) {
164: return false;
165: }
166: return (h >= hue.low() && h <= hue.high());
167:
168: }
169:
170: /**
171: * If there is only one file node, expand it
172: * otherwise, collapse them
173: * When a file node is expanded, all the schema component nodes
174: * in the file are shown. The edge from the file node to the
175: * query node is hidden.
176: *
177: * When a file node is collapsed, all the schema component nodes
178: * in the file are hidden. The edge from the file node to the query
179: * node is shown.
180: *
181: *
182: */
183: public static void expandCollapseFileNodes(List<NodeItem> fileNodes) {
184: Predicate p = null;
185: if (fileNodes == null || fileNodes.size() < 1
186: || fileNodes.get(0) == null) {
187: return;
188: }
189: Visualization vis = fileNodes.get(0).getVisualization();
190:
191: if (fileNodes.size() == 1) {
192: NodeItem n = fileNodes.get(0);
193: n.setBoolean(AnalysisConstants.IS_EXPANDED, true);
194: p = (Predicate) ExpressionParser.parse("["
195: + AnalysisConstants.FILE_GROUP + "] = " + //NOI18N
196: n.getInt(AnalysisConstants.FILE_NODE_FILE_GROUP));
197: vis.setVisible(AnalysisConstants.GRAPH_GROUP, p, true);
198: setFileEdgeVisible(n, false);
199:
200: } else {
201: for (NodeItem n : fileNodes) {
202: n.setBoolean(AnalysisConstants.IS_EXPANDED, false);
203: p = (Predicate) ExpressionParser
204: .parse("["
205: + AnalysisConstants.FILE_GROUP
206: + "] = "
207: + //NOI18N
208: n
209: .getInt(AnalysisConstants.FILE_NODE_FILE_GROUP));
210: vis.setVisible(AnalysisConstants.GRAPH_GROUP, p, false);
211: setFileEdgeVisible(n, true);
212: }
213: }
214: }
215:
216: /**
217: * Set the edge between the file node and query node
218: * visible or not visible
219: *
220: *
221: */
222: private static void setFileEdgeVisible(final NodeItem fileNode,
223: boolean visible) {
224: Iterator outEdges = fileNode.outEdges();
225: while (outEdges.hasNext()) {
226: EdgeItem edge = EdgeItem.class.cast(outEdges.next());
227: if (edge.getString(AnalysisConstants.EDGE_TYPE).equals(
228: AnalysisConstants.FILE_EDGE_TYPE)) {
229: edge.setVisible(visible);
230: }
231: }
232: }
233:
234: /**
235: * create String using HTML and CSS style tag. Example:
236: *"<html>
237: * <head>
238: * </head>
239: * <body>
240: * <p style='color: rgb(169,205,255);
241: * text-align:center;
242: * font-size:130%'>
243: * This is the top line of the tooltip
244: * </p>
245: * <p style='color: rgb(169,169,169);
246: * text-align:center;
247: * font-size:130%'>
248: * This is the second line of the tooltip.
249: * </p>
250: * </body>
251: * </html>"
252: */
253:
254: public static String createHTMLToolTip(ToolTipLine[] lines) {
255: if (lines == null) {
256: return null;
257: }
258: StringBuffer tooltip = new StringBuffer();
259: tooltip.append("<html><head></head><body>");
260: for (ToolTipLine l : lines) {
261: if (l == null) {
262: continue;
263: }
264: tooltip.append("<p style='color: rgb");
265: tooltip.append(l.getColorAsRGBString());
266: tooltip.append(";text-align:");
267: tooltip.append(l.getHorizontalAlignmentAsString());
268: tooltip.append(";font-size:");
269: tooltip.append(l.getFontSizePercentageAsString());
270: tooltip.append("%'>");
271: tooltip.append(l.getText());
272: tooltip.append("</p>");
273: }
274: tooltip.append("</body></html>");
275: return tooltip.toString();
276: }
277:
278: /**
279: * An array of ToolTipLine instances can be passed to
280: * GraphUtilities.createHTMLToolTip()
281: * ToolTipLine contains the text, the font size as a percentage of the default size,
282: * the horizontal alignment (center, left, or right), and the font color.
283: *
284: *
285: */
286: public static class ToolTipLine {
287: public enum HorizontalAlignment {
288: CENTER("center"), // NOI18N
289: LEFT("left"), // NOI18N
290: RIGHT("right"); // NOI18N
291:
292: private final String name;
293:
294: HorizontalAlignment(String name) {
295: this .name = name;
296: }
297:
298: public String toString() {
299: return name;
300: }
301: }
302:
303: private String text = ""; //NOI18N
304: private int fontSizePercentage = 100;
305: private int rgbColor = Color.BLACK.getRGB();
306: private HorizontalAlignment hAlign = HorizontalAlignment.CENTER;
307:
308: public ToolTipLine(String text, int fontSizePercentage,
309: int rgbColor, HorizontalAlignment hAlign) {
310:
311: this .text = text;
312: this .fontSizePercentage = fontSizePercentage;
313: this .rgbColor = rgbColor;
314: this .hAlign = hAlign;
315: }
316:
317: public ToolTipLine(String text, int rgbColor) {
318: this .text = text;
319: this .rgbColor = rgbColor;
320: }
321:
322: public ToolTipLine(String text) {
323: this .text = text;
324: }
325:
326: public String getHorizontalAlignmentAsString() {
327: return this .hAlign.toString();
328: }
329:
330: public String getText() {
331: return " " + this .text + " "; //NOI18N
332: }
333:
334: public String getFontSizePercentageAsString() {
335: return String.valueOf(fontSizePercentage);
336: }
337:
338: // example return value "(145,123,000)"
339: public String getColorAsRGBString() {
340: Color color = new Color(rgbColor);
341: StringBuilder str = new StringBuilder();
342: str.append("("); //NOI18N
343: str.append(String.valueOf(color.getRed()));
344: str.append(","); //NOI18N
345: str.append(String.valueOf(color.getGreen()));
346: str.append(","); //NOI18N
347: str.append(String.valueOf(color.getBlue()));
348: str.append(")"); //NOI18N
349: return str.toString();
350: }
351:
352: }
353:
354: }
|