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 threaddemo.views;
043:
044: import java.io.CharConversionException;
045: import java.util.ArrayList;
046: import java.util.List;
047: import java.util.logging.Level;
048: import java.util.logging.Logger;
049: import javax.swing.Action;
050: import org.netbeans.spi.looks.Look;
051: import org.openide.actions.DeleteAction;
052: import org.openide.util.Lookup;
053: import org.openide.util.actions.SystemAction;
054: import org.openide.xml.XMLUtil;
055: import org.w3c.dom.Attr;
056: import org.w3c.dom.Document;
057: import org.w3c.dom.Element;
058: import org.w3c.dom.NamedNodeMap;
059: import org.w3c.dom.Node;
060: import org.w3c.dom.NodeList;
061: import org.w3c.dom.events.Event;
062: import org.w3c.dom.events.EventListener;
063: import org.w3c.dom.events.EventTarget;
064:
065: // XXX could have other operations - insert etc.
066:
067: /**
068: * Look for a DOM Document or one of its elements.
069: * @author Jesse Glick
070: */
071: public class ElementLook extends Look<Element> implements EventListener {
072:
073: private static final Logger logger = Logger
074: .getLogger(ElementLook.class.getName());
075:
076: public ElementLook() {
077: super ("ElementLook");
078: }
079:
080: public String getDisplayName() {
081: return "DOM Elements";
082: }
083:
084: protected void attachTo(Element e) {
085: EventTarget et = (EventTarget) e;
086: // Node{Inserted,Removed} is fired *before* the change. This is better;
087: // fired *after* it has taken effect.
088: et.addEventListener("DOMSubtreeModified", this , false);
089: }
090:
091: protected void detachFrom(Element e) {
092: EventTarget et = (EventTarget) e;
093: et.removeEventListener("DOMSubtreeModified", this , false);
094: }
095:
096: public void handleEvent(Event evt) {
097: // XXX for some reason, sometimes if refactoring is done while an XML phadhail is
098: // expanded, some infinite loop occurs and this method is called repeatedly
099: try {
100: Element parent = (Element) evt.getCurrentTarget();
101: if (logger.isLoggable(Level.FINER)) {
102: logger.log(Level.FINER,
103: "ElementLook: event on {0}: {1}; co={2}",
104: new Object[] { parent.getTagName(), evt,
105: getChildObjects(parent, null) });
106: }
107: fireChange(parent, Look.GET_CHILD_OBJECTS
108: | Look.GET_DISPLAY_NAME);
109: } catch (RuntimeException e) {
110: e.printStackTrace();
111: }
112: }
113:
114: public String getName(Element e, Lookup env) {
115: return e.getTagName();
116: }
117:
118: public String getDisplayName(Element e, Lookup env) {
119: return fullText(e);
120: }
121:
122: private static String fullText(Element el) {
123: StringBuffer buf = new StringBuffer();
124: buf.append('<');
125: buf.append(el.getNodeName());
126: NamedNodeMap attrs = el.getAttributes();
127: int len = attrs.getLength();
128: for (int i = 0; i < len; i++) {
129: Attr attr = (Attr) attrs.item(i);
130: buf.append(' ');
131: buf.append(attr.getName());
132: buf.append('=');
133: buf.append('"');
134: try {
135: buf.append(XMLUtil.toAttributeValue(attr.getValue()));
136: } catch (CharConversionException e) {
137: e.printStackTrace();
138: }
139: buf.append('"');
140: }
141: if (el.getElementsByTagName("*").getLength() > 0) {
142: // Have some sub-elements.
143: buf.append('>');
144: } else {
145: buf.append("/>");
146: }
147: return buf.toString();
148: }
149:
150: public boolean isLeaf(Element e, Lookup env) {
151: NodeList nl = e.getChildNodes();
152: for (int i = 0; i < nl.getLength(); i++) {
153: if (nl.item(i) instanceof Element) {
154: return false;
155: }
156: }
157: return true;
158: }
159:
160: public List<?> getChildObjects(Element e, Lookup env) {
161: NodeList nl = e.getChildNodes();
162: List<Element> l = new ArrayList<Element>(Math.max(nl
163: .getLength(), 1));
164: for (int i = 0; i < nl.getLength(); i++) {
165: Node n = nl.item(i);
166: if (n instanceof Element) {
167: l.add((Element) n);
168: }
169: }
170: return l;
171: }
172:
173: public boolean canDestroy(Element e, Lookup env) {
174: return !(e.getParentNode() instanceof Document);
175: }
176:
177: public void destroy(Element e, Lookup env) {
178: e.getParentNode().removeChild(e);
179: }
180:
181: public Action[] getActions(Element e, Lookup env) {
182: return new Action[] { SystemAction.get(DeleteAction.class), };
183: }
184:
185: }
|