~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to xml/xsl/api/src/org/netbeans/modules/xslt/model/impl/XslComponentImpl.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
3
 *
 
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 
5
 *
 
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]"
 
23
 *
 
24
 * Contributor(s):
 
25
 *
 
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.
 
29
 *
 
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.
 
40
 */
 
41
 
 
42
package org.netbeans.modules.xslt.model.impl;
 
43
 
 
44
 
 
45
import java.util.ArrayList;
 
46
import java.util.Collection;
 
47
import java.util.Collections;
 
48
import java.util.List;
 
49
 
 
50
import javax.xml.namespace.QName;
 
51
 
 
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;
 
69
 
 
70
 
 
71
/**
 
72
 * @author ads
 
73
 *
 
74
 */
 
75
abstract class XslComponentImpl extends AbstractDocumentComponent<XslComponent>
 
76
    implements XslComponent 
 
77
{
 
78
 
 
79
    XslComponentImpl( XslModelImpl model, Element e ) {
 
80
        super(model, e);
 
81
        myAttributeAccess = new AttributeAccess( this );
 
82
    }
 
83
    
 
84
    XslComponentImpl( XslModelImpl model , XslElements type ) {
 
85
        this( model , createNewElement( type, model) );
 
86
    }
 
87
    
 
88
    public abstract Class<? extends XslComponent> getComponentType();
 
89
 
 
90
 
 
91
    public abstract void accept( XslVisitor visitor );
 
92
 
 
93
    
 
94
    /***************************************************************************
 
95
     * 
 
96
     * The methods below are frequently used in specific impls. So I place them here. 
 
97
     * 
 
98
     *************************************************************************** 
 
99
     */
 
100
    
 
101
    public AttributeValueTemplate createTemplate( QName qName ) {
 
102
        return AttributeValueTemplateImpl.creatAttributeValueTemplate( qName );
 
103
    }
 
104
    
 
105
    public AttributeValueTemplate createTemplate( String value  ) {
 
106
        return AttributeValueTemplateImpl.creatAttributeValueTemplate( this , 
 
107
                value );
 
108
    }
 
109
    
 
110
    
 
111
    public String getSelect() {
 
112
        return getAttribute( XslAttributes.SELECT );
 
113
    }
 
114
 
 
115
    public void setSelect( String select ) {
 
116
        setAttribute( XslAttributes.SELECT, select );
 
117
    }
 
118
    
 
119
    /* (non-Javadoc)
 
120
     * @see org.netbeans.modules.xslt.model.ContentElement#getContent()
 
121
     */
 
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 ) {
 
128
                break;
 
129
            }
 
130
            if (node instanceof Text && ! ( node  instanceof Comment ) ) {
 
131
                text.append(node.getNodeValue());
 
132
            }
 
133
        }
 
134
        return text.toString();
 
135
    }
 
136
 
 
137
    /* (non-Javadoc)
 
138
     * @see org.netbeans.modules.xslt.model.ContentElement#setContent(java.lang.String)
 
139
     */
 
140
    public void setContent( String text ) {
 
141
        verifyWrite();
 
142
        StringBuilder oldValue = new StringBuilder();
 
143
        ArrayList<Node> toRemove = new ArrayList<Node>();
 
144
        NodeList nodeList = getPeer().getChildNodes();
 
145
 
 
146
        Element ref = null;
 
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;
 
151
                break;
 
152
            }
 
153
            if (node instanceof Text &&  node.getNodeType() != Node.COMMENT_NODE) {
 
154
                toRemove.add(node);
 
155
                oldValue.append(node.getNodeValue());
 
156
            }
 
157
        }
 
158
        
 
159
        getModel().getAccess().removeChildren(getPeer(), toRemove, this);
 
160
        if ( text != null) {
 
161
             Text newNode = getModel().getDocument().createTextNode(text);
 
162
             if (ref != null) {
 
163
                getModel().getAccess().insertBefore(getPeer(), newNode, ref, this);
 
164
             } else {
 
165
                getModel().getAccess().appendChild(getPeer(), newNode, this); 
 
166
             }
 
167
        }
 
168
        
 
169
        firePropertyChange(ContentElement.TEXT_CONTENT_PROPERTY, 
 
170
                oldValue == null ? null : oldValue.toString(), text );
 
171
        fireValueChanged();
 
172
    }
 
173
    
 
174
    /* (non-Javadoc)
 
175
     * @see org.netbeans.modules.xslt.model.SequenceElement#getTrailingText()
 
176
     */
 
177
    public String getTrailingText() {
 
178
        XslComponentImpl parent = getParent();
 
179
        if( parent == null ) {
 
180
            return null;
 
181
        }
 
182
        return parent.getTrailingText( this );
 
183
    }
 
184
 
 
185
    /* (non-Javadoc)
 
186
     * @see org.netbeans.modules.xslt.model.SequenceElement#setTrailingText(java.lang.String)
 
187
     */
 
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
 
193
        }
 
194
        parent.setTrailingText( SequenceElement.TEXT_CONTENT_PROPERTY, text, 
 
195
                this );
 
196
    }
 
197
 
 
198
    /*
 
199
     *************************************************************************** 
 
200
     */
 
201
    
 
202
    /*
 
203
     * (non-Javadoc)
 
204
     * @see org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent#getModel()
 
205
     */
 
206
    @Override
 
207
    public XslModelImpl getModel() {
 
208
        return (XslModelImpl)super.getModel();
 
209
    }
 
210
    
 
211
    /* (non-Javadoc)
 
212
     * @see org.netbeans.modules.xml.xam.AbstractComponent#getParent()
 
213
     */
 
214
    @Override
 
215
    public XslComponentImpl getParent() {
 
216
        return (XslComponentImpl)super.getParent();
 
217
    }
 
218
    
 
219
    /* (non-Javadoc)
 
220
     * @see org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent#lookupNamespaceURI(java.lang.String)
 
221
     */
 
222
    @Override
 
223
    public String lookupNamespaceURI(String prefix) {
 
224
        return lookupNamespaceURI(prefix, true);
 
225
    }
 
226
    
 
227
    /* (non-Javadoc)
 
228
     * @see org.netbeans.modules.xslt.model.XslComponent#createReferenceTo(org.netbeans.modules.xslt.model.ReferenceableXslComponent, java.lang.Class)
 
229
     */
 
230
    @SuppressWarnings("unchecked")
 
231
    public <T extends ReferenceableXslComponent> XslReference<T> createReferenceTo( 
 
232
            T referenced, Class<T> type ) 
 
233
    {
 
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 , 
 
238
                this );
 
239
    }
 
240
 
 
241
    /* (non-Javadoc)
 
242
     * @see org.netbeans.modules.xslt.model.XslComponent#fromSameModel(org.netbeans.modules.xslt.model.XslComponent)
 
243
     */
 
244
    public boolean fromSameModel( XslComponent other ) {
 
245
        return getModel().equals(other.getModel());
 
246
    }
 
247
    
 
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);
 
252
    }
 
253
    
 
254
    protected void setAttribute( XslAttributes attribute, 
 
255
            AttributeValueTemplate avt) 
 
256
    {
 
257
        verifyWrite();
 
258
        if( avt == null ) {
 
259
            setAttribute( attribute, (Object)null);
 
260
        }
 
261
        Object resultValue = avt; 
 
262
        if ( !avt.isTemplate() ) {
 
263
            QName qName = avt.getQName();
 
264
            if ( qName!= null ) {
 
265
                resultValue = 
 
266
                    getPrefixedName( qName.getNamespaceURI(), 
 
267
                            qName.getLocalPart(), null, true);
 
268
            }
 
269
        }
 
270
        if ( resultValue instanceof String ) {
 
271
            Object old = null;
 
272
            String s = getAttribute(attribute);
 
273
            if (s != null) {
 
274
                old = getAttributeValueOf(attribute, s);
 
275
            }
 
276
            setAttributeAndFireChange(attribute, (String)resultValue, old, avt );
 
277
        }
 
278
        else {
 
279
            setAttribute(attribute, (Object)avt);
 
280
        }
 
281
    }
 
282
    
 
283
    protected void setAttribute( XslAttributes attribute, Object value ) {
 
284
        setAttribute( attribute.getName() , attribute, value);
 
285
    }
 
286
    
 
287
    protected void setAttributeTokenList( XslAttributes attribute, 
 
288
            List<String> value ) 
 
289
    {
 
290
        setAttribute(attribute, value, Lazy.SIMPLE_STRATEGY );
 
291
    }
 
292
    
 
293
    protected void setAttribute( XslAttributes attribute, 
 
294
            XslReference<? extends ReferenceableXslComponent> value ) 
 
295
    {
 
296
        verifyWrite();
 
297
        if( value == null ) {
 
298
            setAttribute( attribute, (Object)null);
 
299
        }
 
300
        QName qName = value.getQName();
 
301
        assert qName!= null;
 
302
        String resultValue = getPrefixedName( qName.getNamespaceURI(), 
 
303
                            qName.getLocalPart(), null, true);
 
304
        Object old = null;
 
305
        String s = getAttribute(attribute);
 
306
        if (s != null) {
 
307
            old = getAttributeValueOf(attribute, s);
 
308
        }
 
309
        setAttributeAndFireChange(attribute, resultValue, old, value);
 
310
    }
 
311
    
 
312
    protected <T extends QualifiedNameable> GlobalReferenceImpl<T> 
 
313
        resolveGlobalReference( Class<T> clazz, XslAttributes attrName )
 
314
    {
 
315
        String value = getAttribute(attrName);
 
316
        return getAtttributeAccess().resolveGlobalReference(clazz, value);
 
317
    }
 
318
    
 
319
    protected <T extends QualifiedNameable> List<XslReference<T>> 
 
320
        resolveGlobalReferenceList( Class<T> clazz, XslAttributes attrName )
 
321
    {
 
322
        String value = getAttribute(attrName);
 
323
        return getAtttributeAccess().resolveGlobalReferenceList(clazz, value);
 
324
    }
 
325
    
 
326
    @SuppressWarnings("unchecked")
 
327
    protected <T extends ReferenceableXslComponent> void setAttributeList( 
 
328
            XslAttributes attr, List<XslReference<T>> collection ) 
 
329
    {
 
330
        setAttribute( attr, collection, Lazy.REFERENCE_STRATEGY );
 
331
    }
 
332
    
 
333
    protected void setAttribute( XslAttributes attr , List<QName> list ) {
 
334
        setAttribute(attr, list, Lazy.QNAME_STRATEGY );
 
335
    }
 
336
    
 
337
    protected List<QName> getQNameList( String value ){
 
338
        return getAtttributeAccess().getQNameList(value);
 
339
    }
 
340
 
 
341
    /* (non-Javadoc)
 
342
     * @see org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent#getAttributeValueOf(org.netbeans.modules.xml.xam.dom.Attribute, java.lang.String)
 
343
     */
 
344
    @Override
 
345
    protected Object getAttributeValueOf( Attribute attr, String stringValue )
 
346
    {
 
347
        return getAtttributeAccess().getAttributeValueOf(attr, stringValue);
 
348
    }
 
349
    
 
350
    /* (non-Javadoc)
 
351
     * @see org.netbeans.modules.xml.xam.dom.AbstractDocumentComponent#populateChildren(java.util.List)
 
352
     */
 
353
    @Override
 
354
    protected void populateChildren( List<XslComponent> children )
 
355
    {
 
356
        NodeList nl = getPeer().getChildNodes();
 
357
        if (nl != null) {
 
358
            for (int i = 0; i < nl.getLength(); i++) {
 
359
                Node n = nl.item(i);
 
360
                if (n instanceof Element) {
 
361
                    XslComponent comp = (XslComponent) getModel().getFactory()
 
362
                            .create((Element) n, this);
 
363
                    if (comp != null) {
 
364
                        children.add(comp);
 
365
                    }
 
366
                }
 
367
            }
 
368
        }
 
369
    }
 
370
 
 
371
    @Override
 
372
    protected int findDomainIndex(Element e) {
 
373
        int result = super.findDomainIndex( e );
 
374
        if ( result != -1 ) {
 
375
            return result;
 
376
        }
 
377
        
 
378
        // only sequence constructor could have non-xsl components.
 
379
        if ( !( this instanceof SequenceConstructor )) {
 
380
            return -1;
 
381
        }
 
382
        
 
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;
 
389
            }
 
390
            if ( node instanceof Element ) {
 
391
                domainInsertIndex++;
 
392
            }
 
393
        }
 
394
        return -1;
 
395
    }
 
396
    
 
397
    protected String getTrailingText( XslComponent child) {
 
398
        return getText(child, false, false);
 
399
    }
 
400
    
 
401
    protected void setTrailingText(String propName, String text, 
 
402
            XslComponent child ) 
 
403
    {
 
404
        setText(propName, text, child, false, false );
 
405
    }
 
406
    
 
407
    protected static Element createNewElement(XslElements type, XslModelImpl model){
 
408
        return model.getDocument().createElementNS( XSL_NAMESPACE, type.getName());
 
409
    }
 
410
    
 
411
    private AttributeAccess getAtttributeAccess() {
 
412
        return myAttributeAccess;
 
413
    }
 
414
    
 
415
    private <T> void setAttribute( XslAttributes attribute, List<T> list,
 
416
            AttributeListValueStartegy<T> strategy ) 
 
417
    {
 
418
        if ( list == null ) {
 
419
            setAttribute( attribute, list );
 
420
        }
 
421
        verifyWrite();
 
422
        StringBuilder builder = new StringBuilder();
 
423
        for ( T t: list ) {
 
424
            assert t!=null;
 
425
            String resultValue = strategy.toString( t , this );
 
426
            builder.append( resultValue );
 
427
            builder.append( " " );
 
428
        }
 
429
        String result = null;
 
430
        if ( builder.length() > 0 ) {
 
431
            result = builder.substring( 0, builder.length() -1 );
 
432
        }
 
433
        else {
 
434
            result = builder.toString();
 
435
        }
 
436
        Object old = null;
 
437
        String s = getAttribute(attribute);
 
438
        if (s != null) {
 
439
            old = getAttributeValueOf(attribute, s);
 
440
        }
 
441
        setAttributeAndFireChange(attribute, result, old, list );
 
442
    }
 
443
    
 
444
    private void setAttributeAndFireChange( XslAttributes attr , String
 
445
            newStringValue, Object oldValue , Object newValue ) 
 
446
    {
 
447
        setAttributeQuietly(attr, newStringValue );
 
448
        firePropertyChange( attr.getName(), oldValue, newValue );
 
449
        fireValueChanged();
 
450
    }
 
451
 
 
452
    @SuppressWarnings("unchecked")
 
453
    protected static final Collection<Class<? extends XslComponent>> EMPTY = 
 
454
        Collections.EMPTY_LIST;  
 
455
    
 
456
    protected static final Collection<Class<? extends XslComponent>> 
 
457
        SEQUENCE_ELEMENTS = new ArrayList<Class<? extends XslComponent>>(1);
 
458
    
 
459
    private AttributeAccess myAttributeAccess;
 
460
 
 
461
    static {
 
462
        SEQUENCE_ELEMENTS.add( SequenceElement.class );
 
463
    }
 
464
    
 
465
    interface AttributeListValueStartegy<T> {
 
466
        
 
467
        String toString( T token , XslComponentImpl comp );
 
468
    }
 
469
    
 
470
    static class SimpleStrategy implements AttributeListValueStartegy<String> {
 
471
 
 
472
        public String toString( String token , XslComponentImpl comp ) {
 
473
            return token;
 
474
        }
 
475
    }
 
476
    
 
477
    static class ReferenceStrategy<T> implements 
 
478
        AttributeListValueStartegy<T> 
 
479
    {
 
480
 
 
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);
 
486
        }
 
487
    }
 
488
    
 
489
    static class QNameStrategy implements AttributeListValueStartegy<QName> {
 
490
 
 
491
        public String toString( QName token, XslComponentImpl comp ) {
 
492
            return comp.getPrefixedName( token.getNamespaceURI(), 
 
493
                    token.getLocalPart(), null, true);
 
494
        }
 
495
        
 
496
    }
 
497
    
 
498
    static class Lazy {
 
499
        static final SimpleStrategy SIMPLE_STRATEGY = new SimpleStrategy();
 
500
        
 
501
        static final ReferenceStrategy REFERENCE_STRATEGY  = 
 
502
            new ReferenceStrategy();
 
503
        
 
504
        static final QNameStrategy QNAME_STRATEGY = new QNameStrategy();
 
505
    }
 
506
}