2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.xslt.model.impl;
45
import java.util.ArrayList;
46
import java.util.Collection;
47
import java.util.Collections;
48
import java.util.List;
50
import javax.xml.namespace.QName;
52
import org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent;
53
import org.netbeans.modules.xml.xam.dom.Attribute;
54
import org.netbeans.modules.xslt.model.AttributeValueTemplate;
55
import org.netbeans.modules.xslt.model.ContentElement;
56
import org.netbeans.modules.xslt.model.QualifiedNameable;
57
import org.netbeans.modules.xslt.model.ReferenceableXslComponent;
58
import org.netbeans.modules.xslt.model.SequenceConstructor;
59
import org.netbeans.modules.xslt.model.SequenceElement;
60
import org.netbeans.modules.xslt.model.XslComponent;
61
import org.netbeans.modules.xslt.model.XslReference;
62
import org.netbeans.modules.xslt.model.XslVisitor;
63
import org.netbeans.modules.xslt.model.enums.EnumValue;
64
import org.w3c.dom.Comment;
65
import org.w3c.dom.Element;
66
import org.w3c.dom.Node;
67
import org.w3c.dom.NodeList;
68
import org.w3c.dom.Text;
75
abstract class XslComponentImpl extends AbstractDocumentComponent<XslComponent>
76
implements XslComponent
79
XslComponentImpl( XslModelImpl model, Element e ) {
81
myAttributeAccess = new AttributeAccess( this );
84
XslComponentImpl( XslModelImpl model , XslElements type ) {
85
this( model , createNewElement( type, model) );
88
public abstract Class<? extends XslComponent> getComponentType();
91
public abstract void accept( XslVisitor visitor );
94
/***************************************************************************
96
* The methods below are frequently used in specific impls. So I place them here.
98
***************************************************************************
101
public AttributeValueTemplate createTemplate( QName qName ) {
102
return AttributeValueTemplateImpl.creatAttributeValueTemplate( qName );
105
public AttributeValueTemplate createTemplate( String value ) {
106
return AttributeValueTemplateImpl.creatAttributeValueTemplate( this ,
111
public String getSelect() {
112
return getAttribute( XslAttributes.SELECT );
115
public void setSelect( String select ) {
116
setAttribute( XslAttributes.SELECT, select );
120
* @see org.netbeans.modules.xslt.model.ContentElement#getContent()
122
public String getContent() {
123
StringBuilder text = new StringBuilder();
124
NodeList nodeList = getPeer().getChildNodes();
125
for (int i = 0; i < nodeList.getLength(); i++) {
126
Node node = nodeList.item(i);
127
if ( node instanceof Element ) {
130
if (node instanceof Text && ! ( node instanceof Comment ) ) {
131
text.append(node.getNodeValue());
134
return text.toString();
138
* @see org.netbeans.modules.xslt.model.ContentElement#setContent(java.lang.String)
140
public void setContent( String text ) {
142
StringBuilder oldValue = new StringBuilder();
143
ArrayList<Node> toRemove = new ArrayList<Node>();
144
NodeList nodeList = getPeer().getChildNodes();
147
for (int i = 0; i < nodeList.getLength(); i++) {
148
Node node = nodeList.item(i);
149
if (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
150
ref = (Element) node;
153
if (node instanceof Text && node.getNodeType() != Node.COMMENT_NODE) {
155
oldValue.append(node.getNodeValue());
159
getModel().getAccess().removeChildren(getPeer(), toRemove, this);
161
Text newNode = getModel().getDocument().createTextNode(text);
163
getModel().getAccess().insertBefore(getPeer(), newNode, ref, this);
165
getModel().getAccess().appendChild(getPeer(), newNode, this);
169
firePropertyChange(ContentElement.TEXT_CONTENT_PROPERTY,
170
oldValue == null ? null : oldValue.toString(), text );
175
* @see org.netbeans.modules.xslt.model.SequenceElement#getTrailingText()
177
public String getTrailingText() {
178
XslComponentImpl parent = getParent();
179
if( parent == null ) {
182
return parent.getTrailingText( this );
186
* @see org.netbeans.modules.xslt.model.SequenceElement#setTrailingText(java.lang.String)
188
public void setTrailingText( String text ) {
189
XslComponentImpl parent = getParent();
190
if( parent == null ) {
191
throw new IllegalStateException("Trailing text cannot be set for " + // NOI18N
192
"component that doesn't have parent element"); // NOI18N
194
parent.setTrailingText( SequenceElement.TEXT_CONTENT_PROPERTY, text,
199
***************************************************************************
204
* @see org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent#getModel()
207
public XslModelImpl getModel() {
208
return (XslModelImpl)super.getModel();
212
* @see org.netbeans.modules.xml.xam.AbstractComponent#getParent()
215
public XslComponentImpl getParent() {
216
return (XslComponentImpl)super.getParent();
220
* @see org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent#lookupNamespaceURI(java.lang.String)
223
public String lookupNamespaceURI(String prefix) {
224
return lookupNamespaceURI(prefix, true);
228
* @see org.netbeans.modules.xslt.model.XslComponent#createReferenceTo(org.netbeans.modules.xslt.model.ReferenceableXslComponent, java.lang.Class)
230
@SuppressWarnings("unchecked")
231
public <T extends ReferenceableXslComponent> XslReference<T> createReferenceTo(
232
T referenced, Class<T> type )
234
// currently we only know how to resolve QualifiedNameable elements.
235
// later this impl could be changed respectively.
236
assert type.isAssignableFrom( QualifiedNameable.class );
237
return new GlobalReferenceImpl( (QualifiedNameable) referenced , type ,
242
* @see org.netbeans.modules.xslt.model.XslComponent#fromSameModel(org.netbeans.modules.xslt.model.XslComponent)
244
public boolean fromSameModel( XslComponent other ) {
245
return getModel().equals(other.getModel());
248
protected void setAttribute( XslAttributes attribute, EnumValue value ) {
249
assert value==null || !value.isInvalid() :
250
"Attempt to set up invalid enumeration value"; // NOI18N
251
setAttribute( attribute, (Object)value);
254
protected void setAttribute( XslAttributes attribute,
255
AttributeValueTemplate avt)
259
setAttribute( attribute, (Object)null);
261
Object resultValue = avt;
262
if ( !avt.isTemplate() ) {
263
QName qName = avt.getQName();
264
if ( qName!= null ) {
266
getPrefixedName( qName.getNamespaceURI(),
267
qName.getLocalPart(), null, true);
270
if ( resultValue instanceof String ) {
272
String s = getAttribute(attribute);
274
old = getAttributeValueOf(attribute, s);
276
setAttributeAndFireChange(attribute, (String)resultValue, old, avt );
279
setAttribute(attribute, (Object)avt);
283
protected void setAttribute( XslAttributes attribute, Object value ) {
284
setAttribute( attribute.getName() , attribute, value);
287
protected void setAttributeTokenList( XslAttributes attribute,
290
setAttribute(attribute, value, Lazy.SIMPLE_STRATEGY );
293
protected void setAttribute( XslAttributes attribute,
294
XslReference<? extends ReferenceableXslComponent> value )
297
if( value == null ) {
298
setAttribute( attribute, (Object)null);
300
QName qName = value.getQName();
302
String resultValue = getPrefixedName( qName.getNamespaceURI(),
303
qName.getLocalPart(), null, true);
305
String s = getAttribute(attribute);
307
old = getAttributeValueOf(attribute, s);
309
setAttributeAndFireChange(attribute, resultValue, old, value);
312
protected <T extends QualifiedNameable> GlobalReferenceImpl<T>
313
resolveGlobalReference( Class<T> clazz, XslAttributes attrName )
315
String value = getAttribute(attrName);
316
return getAtttributeAccess().resolveGlobalReference(clazz, value);
319
protected <T extends QualifiedNameable> List<XslReference<T>>
320
resolveGlobalReferenceList( Class<T> clazz, XslAttributes attrName )
322
String value = getAttribute(attrName);
323
return getAtttributeAccess().resolveGlobalReferenceList(clazz, value);
326
@SuppressWarnings("unchecked")
327
protected <T extends ReferenceableXslComponent> void setAttributeList(
328
XslAttributes attr, List<XslReference<T>> collection )
330
setAttribute( attr, collection, Lazy.REFERENCE_STRATEGY );
333
protected void setAttribute( XslAttributes attr , List<QName> list ) {
334
setAttribute(attr, list, Lazy.QNAME_STRATEGY );
337
protected List<QName> getQNameList( String value ){
338
return getAtttributeAccess().getQNameList(value);
342
* @see org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent#getAttributeValueOf(org.netbeans.modules.xml.xam.dom.Attribute, java.lang.String)
345
protected Object getAttributeValueOf( Attribute attr, String stringValue )
347
return getAtttributeAccess().getAttributeValueOf(attr, stringValue);
351
* @see org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent#populateChildren(java.util.List)
354
protected void populateChildren( List<XslComponent> children )
356
NodeList nl = getPeer().getChildNodes();
358
for (int i = 0; i < nl.getLength(); i++) {
360
if (n instanceof Element) {
361
XslComponent comp = (XslComponent) getModel().getFactory()
362
.create((Element) n, this);
372
protected int findDomainIndex(Element e) {
373
int result = super.findDomainIndex( e );
374
if ( result != -1 ) {
378
// only sequence constructor could have non-xsl components.
379
if ( !( this instanceof SequenceConstructor )) {
383
int domainInsertIndex = 0;
384
NodeList list = getPeer().getChildNodes();
385
for (int i=0; i<list.getLength(); i++) {
386
Node node = list.item( i );
387
if (list.item(i) == e) {
388
return domainInsertIndex;
390
if ( node instanceof Element ) {
397
protected String getTrailingText( XslComponent child) {
398
return getText(child, false, false);
401
protected void setTrailingText(String propName, String text,
404
setText(propName, text, child, false, false );
407
protected static Element createNewElement(XslElements type, XslModelImpl model){
408
return model.getDocument().createElementNS( XSL_NAMESPACE, type.getName());
411
private AttributeAccess getAtttributeAccess() {
412
return myAttributeAccess;
415
private <T> void setAttribute( XslAttributes attribute, List<T> list,
416
AttributeListValueStartegy<T> strategy )
418
if ( list == null ) {
419
setAttribute( attribute, list );
422
StringBuilder builder = new StringBuilder();
425
String resultValue = strategy.toString( t , this );
426
builder.append( resultValue );
427
builder.append( " " );
429
String result = null;
430
if ( builder.length() > 0 ) {
431
result = builder.substring( 0, builder.length() -1 );
434
result = builder.toString();
437
String s = getAttribute(attribute);
439
old = getAttributeValueOf(attribute, s);
441
setAttributeAndFireChange(attribute, result, old, list );
444
private void setAttributeAndFireChange( XslAttributes attr , String
445
newStringValue, Object oldValue , Object newValue )
447
setAttributeQuietly(attr, newStringValue );
448
firePropertyChange( attr.getName(), oldValue, newValue );
452
@SuppressWarnings("unchecked")
453
protected static final Collection<Class<? extends XslComponent>> EMPTY =
454
Collections.EMPTY_LIST;
456
protected static final Collection<Class<? extends XslComponent>>
457
SEQUENCE_ELEMENTS = new ArrayList<Class<? extends XslComponent>>(1);
459
private AttributeAccess myAttributeAccess;
462
SEQUENCE_ELEMENTS.add( SequenceElement.class );
465
interface AttributeListValueStartegy<T> {
467
String toString( T token , XslComponentImpl comp );
470
static class SimpleStrategy implements AttributeListValueStartegy<String> {
472
public String toString( String token , XslComponentImpl comp ) {
477
static class ReferenceStrategy<T> implements
478
AttributeListValueStartegy<T>
481
public String toString( T token , XslComponentImpl comp ) {
482
assert token instanceof XslReference;
483
QName qName = ((XslReference)token).getQName();
484
return comp.getPrefixedName( qName.getNamespaceURI(),
485
qName.getLocalPart(), null, true);
489
static class QNameStrategy implements AttributeListValueStartegy<QName> {
491
public String toString( QName token, XslComponentImpl comp ) {
492
return comp.getPrefixedName( token.getNamespaceURI(),
493
token.getLocalPart(), null, true);
499
static final SimpleStrategy SIMPLE_STRATEGY = new SimpleStrategy();
501
static final ReferenceStrategy REFERENCE_STRATEGY =
502
new ReferenceStrategy();
504
static final QNameStrategy QNAME_STRATEGY = new QNameStrategy();