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-2007 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:
043: ============================================================================
044: The Apache Software License, Version 1.1
045: ============================================================================
046:
047: Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
048:
049: Redistribution and use in source and binary forms, with or without modifica-
050: tion, are permitted provided that the following conditions are met:
051:
052: 1. Redistributions of source code must retain the above copyright notice,
053: this list of conditions and the following disclaimer.
054:
055: 2. Redistributions in binary form must reproduce the above copyright notice,
056: this list of conditions and the following disclaimer in the documentation
057: and/or other materials provided with the distribution.
058:
059: 3. The end-user documentation included with the redistribution, if any, must
060: include the following acknowledgment: "This product includes software
061: developed by the Apache Software Foundation (http://www.apache.org/)."
062: Alternately, this acknowledgment may appear in the software itself, if
063: and wherever such third-party acknowledgments normally appear.
064:
065: 4. The names "Batik" and "Apache Software Foundation" must not be
066: used to endorse or promote products derived from this software without
067: prior written permission. For written permission, please contact
068: apache@apache.org.
069:
070: 5. Products derived from this software may not be called "Apache", nor may
071: "Apache" appear in their name, without prior written permission of the
072: Apache Software Foundation.
073:
074: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
075: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
076: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
077: APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
078: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
079: DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
080: OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
081: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
082: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
083: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
084:
085: This software consists of voluntary contributions made by many individuals
086: on behalf of the Apache Software Foundation. For more information on the
087: Apache Software Foundation, please see <http://www.apache.org/>.
088:
089: */
090: package org.netbeans.modules.visualweb.designer.markup;
091:
092: import org.netbeans.modules.visualweb.api.designerapi.DesignerServiceHack;
093: import org.netbeans.modules.visualweb.api.insync.InSyncService;
094: import java.net.URL;
095:
096: import org.apache.batik.css.engine.CSSEngine;
097: import org.apache.batik.css.engine.CSSStylableElement;
098: import org.apache.batik.css.engine.StyleMap;
099: import org.apache.xerces.dom.CoreDocumentImpl;
100: import org.w3c.dom.DOMException;
101:
102: import java.lang.ref.WeakReference;
103: import org.w3c.dom.Attr;
104:
105: // if you need to look at older CVS history
106:
107: /**
108: * XXX Originally in insync.
109: *
110: * This class is attempts to merge in Batik specific "StylableElement" interface
111: * implementations with Xerces nodes. That way we can continue to use Xerces2 for
112: * parsing, and reuse a lot of the batik CSS handling code.
113: * This was derived from Batik's org.apache.batik.dom.SVGStylableElement class
114: * with a lot of SVG stuff thrown in, and subclassed for Xerces' Element classes
115: * instead, so I've left the original license/copyright on the file.
116: * However, most of the file here is new (not copied from Batik) and deals with
117: * other aspects of our own DOM needs.
118: *
119: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
120: * @author Tor Norbye
121: */
122: class RaveElement extends org.apache.xerces.dom.ElementNSImpl implements
123: CSSStylableElement, CSSEngine.StyleElementLink /*, RaveElement*/{
124: private static final long serialVersionUID = 3546078060169606198L;
125:
126: /**
127: * The computed style map.
128: */
129: // protected StyleMap computedStyleMap;
130: // private transient CSSStylableElement styleLink;
131: // ----------------------------------------------------------------
132: // TODO - remember to update copyFrom if you add additional fields!
133: // ----------------------------------------------------------------
134: // private transient boolean jspx;
135: // private transient MarkupDesignBean bean;
136: // private transient MarkupMouseRegion region;
137: // XXX This seems to be a dummy field now.
138: /** @todo replace usage with alternate/source/rendered */
139: // transient RaveElement source;
140: // /** Flag which indicates whether this node lives in the "source" DOM (typically the JSP file)
141: // * or the "rendered" DOM (typically the HTML file). I chose to use "render"/"source" terms
142: // * instead of HTML/JSP terms since the JSP can itself contain HTML markup which might muddy the
143: // * issue. */
144: // private transient boolean rendered;
145: //
146: // /** If this is a "rendered" node (see {@link isRendered} then alternate points to its JSP
147: // * source node, and if this is a node in the source DOM (the JSP itself), then alternate
148: // * will point to the first, top level HTML node rendered from this node. HTML markup
149: // * in the JSP will have a 1-1 mapping to HTML markup in the rendered DOM. For JSF components,
150: // * only the top level HTML rendered elements will point back to the source JSP node; children
151: // * will be null indicating that they have no direct alternate node.
152: // */
153: // private transient RaveElement alternate;
154: protected RaveElement() {
155: }
156:
157: protected RaveElement(CoreDocumentImpl ownerDocument,
158: String namespaceURI, String qualifiedName)
159: throws DOMException {
160: super (ownerDocument, namespaceURI, qualifiedName);
161: }
162:
163: protected RaveElement(CoreDocumentImpl ownerDocument,
164: String namespaceURI, String qualifiedName, String localName)
165: throws DOMException {
166: super (ownerDocument, namespaceURI, qualifiedName, localName);
167: }
168:
169: // XXX Batik
170: /**
171: * Returns the computed style of this element/pseudo-element.
172: */
173: public StyleMap getComputedStyleMap(String pseudoElement) {
174: // return computedStyleMap;
175: return MarkupServiceImpl.getElementStyleMap(this );
176: }
177:
178: // XXX Batik
179: /**
180: * Sets the computed style of this element/pseudo-element.
181: */
182: public void setComputedStyleMap(String pseudoElement, StyleMap sm) {
183: // computedStyleMap = sm;
184: MarkupServiceImpl.setElementStyleMap(this , sm);
185: }
186:
187: // XXX Batik
188: /**
189: * Returns the ID of this element.
190: */
191: public String getXMLId() {
192: return getAttributeNS(null, "id");
193: }
194:
195: // // XXX #105179 Performance, very slow impl of NamedNodesMap,
196: // // it uses a linear search.
197: // private WeakReference<String> classWRef = new WeakReference(null);
198: // XXX Batik
199: private WeakReference<Attr> attrRef = null;
200: private String cachedValue = null;
201:
202: /**
203: * Returns the class of this element.
204: */
205: public String getCSSClass() {
206: Attr attr = (attrRef == null) ? null : attrRef.get();
207:
208: if (attr == null) {
209: attr = getAttrNS(null, "class");
210: if (attr == null) {
211: return "";
212: } else {
213: attrRef = new WeakReference<Attr>(attr);
214: cachedValue = attr.getValue();
215: return cachedValue;
216: }
217: } else {
218: return cachedValue;
219: }
220: // String cl = classWRef.get();
221: // if (cl == null) {
222: // cl = getAttributeNS(null, "class"); // NOI18N
223: }
224:
225: public Attr getAttrNS(String namespaceURI, String localName) {
226:
227: if (needsSyncData()) {
228: synchronizeData();
229: }
230:
231: if (attributes == null) {
232: return null;
233: }
234:
235: Attr attr = (Attr) (attributes.getNamedItemNS(namespaceURI,
236: localName));
237: return attr;
238:
239: }
240:
241: final boolean needsSyncData() {
242: return (flags & SYNCDATA) != 0;
243: }
244:
245: // XXX Batik
246: /**
247: * Returns the CSS base URL of this element.
248: */
249: public URL getCSSBase() {
250: // //String bu = XMLBaseSupport.getCascadedXMLBase(this);
251: // URL bu = MarkupUtilities.getCascadedXMLBase(this);
252: //
253: // if (bu == null) {
254: // return null;
255: // }
256: //
257: // //return new URL(bu);
258: // return bu;
259: return MarkupUtilities.getCascadedXMLBase(this );
260: }
261:
262: // XXX Batik
263: /**
264: * Tells whether this element is an instance of the given pseudo
265: * class.
266: */
267: public boolean isPseudoInstanceOf(String pseudoClass) {
268: // if (pseudoClass.equals("first-child")) {
269: // Node n = getPreviousSibling();
270: //
271: // while ((n != null) && (n.getNodeType() != ELEMENT_NODE)) {
272: // n = n.getPreviousSibling();
273: // }
274: //
275: // return n == null;
276: // } else if (pseudoClass.equals("link")) {
277: // Node n = this;
278: // String a = HtmlTag.A.toString();
279: //
280: // while (n != null) {
281: // if ((n.getNodeType() == Node.ELEMENT_NODE) && n.getNodeName().equals(a)) {
282: // // Only a link if the href attribute is set!
283: // if (((Element)n).hasAttribute(HtmlAttribute.HREF)) {
284: // return true;
285: // }
286: // }
287: //
288: // n = n.getParentNode();
289: // }
290: //
291: // return false;
292: // }
293: //
294: // return false;
295: return MarkupServiceImpl.isElementPseudoInstanceOf(this ,
296: pseudoClass);
297: }
298:
299: // public CSSEngine getEngine() {
300: //// return ((RaveDocument)getOwnerDocument()).getCssEngine();
301: // return CssEngineServiceProvider.getDefault().getCssEngine(getOwnerDocument());
302: // }
303:
304: // XXX Batik
305: public void setStyleParent(CSSStylableElement styleLink) {
306: // this.styleLink = styleLink;
307: MarkupServiceImpl.setElementStyleParent(this , styleLink);
308: }
309:
310: // XXX Batik
311: public CSSStylableElement getStyleParent() {
312: // return styleLink;
313: return MarkupServiceImpl.getElementStyleParent(this );
314: }
315:
316: /** During a clone operation, copy relevant info from the given
317: * source element to this target element
318: */
319: // void copyFrom(RaveElementImpl from) {
320: void copyFrom(RaveElement from) {
321: // XXX Replacement for previous direct usage.
322: // TODO Investigate if this is needed, there may not be
323: // the same view for different models.
324: DesignerServiceHack.getDefault().copyBoxForElement(from, this );
325:
326: // this.bean = from.bean;
327: InSyncService.getProvider().copyMarkupDesignBeanForElement(
328: from, this );
329: // this.source = from.getSourceElement();
330: // this.styleLink = from.styleLink;
331: // setStyleParent(from.getStyleParent());
332: MarkupServiceImpl.setElementStyleParent(this , MarkupServiceImpl
333: .getElementStyleParent(from));
334:
335: // this.region = from.region;
336: InSyncService.getProvider().copyMarkupMouseRegionForElement(
337: from, this );
338: }
339:
340: // // ------------ Implements DesignBeanElement ------------------------
341: // public MarkupDesignBean getDesignBean() {
342: // return bean;
343: // }
344: //
345: // public void setDesignBean(MarkupDesignBean bean) {
346: // this.bean = bean;
347: // }
348:
349: // public void setMarkupMouseRegion(MarkupMouseRegion region) {
350: // this.region = region;
351: // }
352: //
353: // public MarkupMouseRegion getMarkupMouseRegion() {
354: // return region;
355: // }
356:
357: // /** Return the source element for this element, if different.
358: // * For example, when a div element is a child of a h:form element,
359: // * it gets rendered into the h:form document fragment. The source
360: // * element for the div will be the div in the jsp. For elements
361: // * in the jsp, getSourceElement just returns itself.
362: // * @todo Get rid of this (but first figure out how to replace it
363: // * by getSource in the presence of jsp node duplication)
364: // * @deprecated This should go away in favor of getSource() -- which is
365: // * not yet equivalent. Clean these up.
366: // */
367: // public RaveElement getSourceElement() {
368: // if (source == null) {
369: // return this;
370: // } else {
371: // return source;
372: // }
373: // }
374:
375: // /**
376: // * Set the virtual parent
377: // */
378: // public static void setStyleParent(Element e, Element p) {
379: // if (e instanceof CSSStylableElement && p instanceof CSSStylableElement) {
380: // CSSEngine.StyleElementLink link = (CSSEngine.StyleElementLink)e;
381: // link.setStyleParent((CSSStylableElement)p);
382: // }
383: // }
384:
385: // public boolean isRendered() {
386: // return rendered;
387: // }
388: // public abstract boolean isRendered();
389:
390: // public RaveElement getRendered() {
391: // if (rendered) {
392: // // TODO - should anyone ask for this if they already have HTML ? The code
393: // // might be confused so perhaps I should assert on this instead to pinpoint
394: // // questionable code...
395: // return this;
396: // }
397: //
398: // return alternate;
399: // }
400: //
401: // public RaveElement getSource() {
402: // if (!rendered) {
403: // // TODO - should anyone ask for this if they already have JSP ? The code
404: // // might be confused so perhaps I should assert on this instead to pinpoint
405: // // questionable code...
406: // return this;
407: // }
408: //
409: // return alternate;
410: // }
411: //
412: // public void setSource(RaveElement source) {
413: // rendered = true;
414: // alternate = source;
415: //
416: // // Make the source have a render reference to this element too, unless
417: // // we know it's a nonvisual element that I'll never need a reference from.
418: // // (And because some components can render script or style tags at the top
419: // // level next to the bean render, it's important not to clobber the render
420: // // pointer here.)
421: // String name = getTagName();
422: //
423: // // Don't store references to invisible markup (<script>, <style>, <input hidden>)
424: // if (alternate != null) {
425: // char first = name.charAt(0);
426: //
427: // if (!(((first == 's') &&
428: // (name.equals(HtmlTag.SCRIPT.name) || name.equals(HtmlTag.STYLE.name))) ||
429: // ((first == 'i') && (name.equals(HtmlTag.INPUT.name)) &&
430: // getAttribute(HtmlAttribute.TYPE).equals("hidden")))) { // NOI18N
431: // ((RaveElementImpl)alternate).rendered = false;
432: // ((RaveElementImpl)alternate).alternate = this;
433: // }
434: // }
435: // }
436: //
437: // public void setRendered(RaveElement rendered) {
438: // this.rendered = false;
439: // alternate = rendered;
440: //
441: // if (alternate != null) {
442: // ((RaveElementImpl)alternate).rendered = true;
443: // ((RaveElementImpl)alternate).alternate = this;
444: // }
445: // }
446:
447: // public boolean isJspx() {
448: //// return jspx;
449: // }
450: //
451: // public void setJspx(boolean jspx) {
452: //// this.jspx = jspx;
453: // }
454:
455: // public /*RaveRenderNode*/ Node getSourceNode() {
456: // return getSource();
457: // }
458: //
459: // public /*RaveRenderNode*/ Node getRenderedNode() {
460: // return getRendered();
461: // }
462:
463: // public void markRendered() {
464: // this.rendered = true;
465: // }
466:
467: public String toString() {
468: // XXX The first part copied from Object.toString, because it was hidden by the superclass.
469: return getClass().getName() + "@"
470: + Integer.toHexString(hashCode())
471: // + "[" + getTagName() + "], id=" + getAttribute("id") + ", rendered=" + rendered;
472: + "[tagName=" + getTagName() + ", id="
473: + getAttribute("id") + "]"/*+ ", rendered=" + isRendered()*/; // NOI18N
474: }
475:
476: }
|