All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spinjar.com.sun.xml.txw2.StartTag Maven / Gradle / Ivy

There is a newer version: 1.23.0
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2005-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.xml.txw2;

import javax.xml.namespace.QName;


/**
 * Start tag.
 *
 * 

* This object implements {@link NamespaceResolver} for attribute values. * * @author Kohsuke Kawaguchi */ class StartTag extends Content implements NamespaceResolver { /** * Tag name of the element. * *

* This field is also used as a flag to indicate * whether the start tag has been written. * This field is initially set to non-null, and * then reset to null when it's written. */ private String uri; // but we keep the local name non-null so that // we can diagnose an error private final String localName; private Attribute firstAtt; private Attribute lastAtt; /** * If this {@link StartTag} has the parent {@link ContainerElement}, * that value. Otherwise null. */ private ContainerElement owner; /** * Explicitly given namespace declarations on this element. * *

* Additional namespace declarations might be necessary to * generate child {@link QName}s and attributes. */ private NamespaceDecl firstNs; private NamespaceDecl lastNs; final Document document; public StartTag(ContainerElement owner, String uri, String localName) { this(owner.document,uri,localName); this.owner = owner; } public StartTag(Document document, String uri, String localName) { assert uri!=null; assert localName!=null; this.uri = uri; this.localName = localName; this.document = document; // TODO: think about a better way to maintain namespace decls. // this requires at least one NamespaceDecl per start tag, // which is rather expensive. addNamespaceDecl(uri,null,false); } public void addAttribute(String nsUri, String localName, Object arg) { checkWritable(); // look for the existing ones Attribute a; for(a=firstAtt; a!=null; a=a.next) { if(a.hasName(nsUri,localName)) { break; } } // if not found, declare a new one if(a==null) { a = new Attribute(nsUri,localName); if(lastAtt==null) { assert firstAtt==null; firstAtt = lastAtt = a; } else { assert firstAtt!=null; lastAtt.next = a; lastAtt = a; } if(nsUri.length()>0) addNamespaceDecl(nsUri,null,true); } document.writeValue(arg,this,a.value); } /** * Declares a new namespace URI on this tag. * * @param uri * namespace URI to be bound. Can be empty, but must not be null. * @param prefix * If non-null and non-empty, this prefix is bound to the URI * on this element. If empty, then the runtime will still try to * use the URI as the default namespace, but it may fail to do so * because of the constraints in the XML. *

* If this parameter is null, the runtime will allocate an unique prefix. * @param requirePrefix * Used only when the prefix parameter is null. If true, this indicates * that the non-empty prefix must be assigned to this URI. If false, * then this URI might be used as the default namespace. *

* Normally you just need to set it to false. */ public NamespaceDecl addNamespaceDecl(String uri, String prefix,boolean requirePrefix) { checkWritable(); if(uri==null) throw new IllegalArgumentException(); if(uri.length()==0) { if(requirePrefix) throw new IllegalArgumentException("The empty namespace cannot have a non-empty prefix"); if(prefix!=null && prefix.length()>0) throw new IllegalArgumentException("The empty namespace can be only bound to the empty prefix"); prefix = ""; } // check for the duplicate for(NamespaceDecl n=firstNs; n!=null; n=n.next) { if(uri.equals(n.uri)) { if(prefix==null) { // reuse this binding n.requirePrefix |= requirePrefix; return n; } if(n.prefix==null) { // reuse this binding n.prefix = prefix; n.requirePrefix |= requirePrefix; return n; } if(prefix.equals(n.prefix)) { // reuse this binding n.requirePrefix |= requirePrefix; return n; } } if(prefix!=null && n.prefix!=null && n.prefix.equals(prefix)) throw new IllegalArgumentException( "Prefix '"+prefix+"' is already bound to '"+n.uri+'\''); } NamespaceDecl ns = new NamespaceDecl(document.assignNewId(),uri,prefix,requirePrefix); if(lastNs==null) { assert firstNs==null; firstNs = lastNs = ns; } else { assert firstNs!=null; lastNs.next = ns; lastNs = ns; } return ns; } /** * Throws an error if the start tag has already been committed. */ private void checkWritable() { if(isWritten()) throw new IllegalStateException( "The start tag of "+this.localName+" has already been written. " + "If you need out of order writing, see the TypedXmlWriter.block method"); } /** * Returns true if this start tag has already been written. */ boolean isWritten() { return uri==null; } /** * A {@link StartTag} can be only written after * we are sure that all the necessary namespace declarations are given. */ boolean isReadyToCommit() { if(owner!=null && owner.isBlocked()) return false; for( Content c=getNext(); c!=null; c=c.getNext() ) if(c.concludesPendingStartTag()) return true; return false; } public void written() { firstAtt = lastAtt = null; uri = null; if(owner!=null) { assert owner.startTag==this; owner.startTag = null; } } boolean concludesPendingStartTag() { return true; } void accept(ContentVisitor visitor) { visitor.onStartTag(uri,localName,firstAtt,firstNs); } public String getPrefix(String nsUri) { NamespaceDecl ns = addNamespaceDecl(nsUri,null,false); if(ns.prefix!=null) // if the prefix has already been declared, use it. return ns.prefix; return ns.dummyPrefix; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy