Java tutorial
/* * Copyright 2004-2012 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.mayaa.impl.engine.specification; import java.io.Serializable; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.seasar.mayaa.engine.specification.CopyToFilter; import org.seasar.mayaa.engine.specification.Namespace; import org.seasar.mayaa.engine.specification.NodeAttribute; import org.seasar.mayaa.engine.specification.NodeObject; import org.seasar.mayaa.engine.specification.NodeTreeWalker; import org.seasar.mayaa.engine.specification.PrefixMapping; import org.seasar.mayaa.engine.specification.QName; import org.seasar.mayaa.engine.specification.Specification; import org.seasar.mayaa.engine.specification.SpecificationNode; import org.seasar.mayaa.engine.specification.URI; import org.seasar.mayaa.engine.specification.serialize.NodeReferenceResolver; import org.seasar.mayaa.impl.CONST_IMPL; import org.seasar.mayaa.impl.util.StringUtil; import org.seasar.mayaa.impl.util.collection.NullIterator; /** * @author Masataka Kurihara (Gluegent, Inc.) */ public class SpecificationNodeImpl extends NamespaceImpl implements SpecificationNode, CONST_IMPL { private static final long serialVersionUID = 7084397580802643259L; private static final Log LOG = LogFactory.getLog(SpecificationNodeImpl.class); private static final CopyToFilter FILTER_ALL = new AllCopyToFilter(); private int _sequenceID = -1; private String _id = null; private Map/*<qName, NodeAttribute>*/ _attributes; private NodeTreeWalkerImpl _delegateNodeTreeWalker; // for PrefixAwareName private QName _qName; private transient String _finalizeLabel; public SpecificationNodeImpl(QName qName) { _qName = qName; } protected NodeTreeWalker getNodeTreeWalker() { if (_delegateNodeTreeWalker == null) { synchronized (this) { _delegateNodeTreeWalker = new NodeTreeWalkerImpl(); _delegateNodeTreeWalker.setOwner(this); if (LOG.isTraceEnabled()) { LOG.trace("_delegateNodeTreeWalker created."); } } } return _delegateNodeTreeWalker; } protected String makeReleasedLabel() { if (_finalizeLabel == null) { try { _finalizeLabel = toString(); } catch (Throwable e) { _finalizeLabel = getNodeTreeWalker().getSystemID() + " <" + _qName + ">"; } } if (_finalizeLabel != null) { return "node " + _finalizeLabel + "@" + hashCode() + " unloaded."; } return ""; } public String toString() { StringBuffer path = new StringBuffer(); if (getParentNode() != null && getParentNode() instanceof Specification == false) { path.append(getParentNode()); } path.append("/"); path.append(PrefixAwareNameImpl.forPrefixAwareNameString(getQName(), getPrefix())); return path.toString(); } // ???????????finalize()???Finalizer????? // protected void finalize() throws Throwable { // if (LOG.isTraceEnabled()) { // LOG.trace(makeReleasedLabel()); // } // super.finalize(); // } // PrefixAwareName implements public QName getQName() { return _qName; } public String getPrefix() { URI namespaceURI = getQName().getNamespaceURI(); for (Iterator it = iteratePrefixMapping(true); it.hasNext();) { PrefixMapping mapping = (PrefixMapping) it.next(); if (namespaceURI.equals(mapping.getNamespaceURI())) { return mapping.getPrefix(); } } return ""; } // SpecificaitonNode implements ------------------------------------ public void setSequenceID(int sequenceID) { if (sequenceID < 0) { throw new IllegalArgumentException("sequenceID"); } _sequenceID = sequenceID; _id = _qName.toString() + ":" + getSystemID() + ":" + _sequenceID; } public int getSequenceID() { return _sequenceID; } public void addAttribute(QName qName, String value) { addAttribute(qName, null, value); } public void addAttribute(QName qName, String originalName, String value) { if (qName == null || value == null) { throw new IllegalArgumentException(); } synchronized (this) { if (_attributes == null) { _attributes = new LinkedHashMap(); } } synchronized (_attributes) { if (_attributes.containsKey(qName) == false) { String prefix = null; if (originalName != null) { prefix = StringUtil.parsePrefix(originalName); } NodeAttributeImpl attr = new NodeAttributeImpl(qName, value, prefix); _attributes.put(qName, attr); attr.setNode(this); } } } public NodeAttribute getAttribute(QName qName) { if (qName == null) { throw new IllegalArgumentException(); } if (_attributes == null) { return null; } return (NodeAttribute) _attributes.get(qName); } public Iterator iterateAttribute() { if (_attributes == null) { return NullIterator.getInstance(); } return _attributes.values().iterator(); } public NodeAttribute removeAttribute(QName qName) { if (_attributes != null) { synchronized (_attributes) { return (NodeAttribute) _attributes.remove(qName); } } return null; } public void clearAttributes() { if (_attributes != null) { synchronized (_attributes) { _attributes.clear(); } } } public SpecificationNode copyTo(CopyToFilter filter) { SpecificationNode copy = SpecificationUtil.createSpecificationNode(getQName(), getSystemID(), getLineNumber(), isOnTemplate(), getSequenceID()); for (Iterator it = iterateAttribute(); it.hasNext();) { NodeAttribute attr = (NodeAttribute) it.next(); if (filter.accept(attr)) { copy.addAttribute(attr.getQName(), attr.getValue()); } } for (Iterator it = iterateChildNode(); it.hasNext();) { SpecificationNode node = (SpecificationNode) it.next(); if (filter.accept(node)) { copy.addChildNode(node.copyTo(filter)); } } for (Iterator it = iteratePrefixMapping(false); it.hasNext();) { PrefixMapping prefixMapping = (PrefixMapping) it.next(); copy.addPrefixMapping(prefixMapping.getPrefix(), prefixMapping.getNamespaceURI()); } copy.setParentSpace(SpecificationUtil.getFixedNamespace(getParentSpace())); copy.setDefaultNamespaceURI(getDefaultNamespaceURI()); return copy; } public SpecificationNode copyTo() { return copyTo(FILTER_ALL); } public void kill() { // TODO deprecated ??? } // NodeTreeWalker implemetns ------------------------------------ public void setParentNode(NodeTreeWalker parent) { getNodeTreeWalker().setParentNode(parent); } public NodeTreeWalker getParentNode() { return getNodeTreeWalker().getParentNode(); } public void addChildNode(NodeTreeWalker childNode) { getNodeTreeWalker().addChildNode(childNode); } public void insertChildNode(int index, NodeTreeWalker childNode) { getNodeTreeWalker().insertChildNode(index, childNode); } public Iterator iterateChildNode() { return getNodeTreeWalker().iterateChildNode(); } public boolean removeChildNode(NodeTreeWalker node) { return getNodeTreeWalker().removeChildNode(node); } public NodeTreeWalker getChildNode(int index) { return getNodeTreeWalker().getChildNode(index); } public int getChildNodeSize() { return getNodeTreeWalker().getChildNodeSize(); } public void clearChildNodes() { if (_delegateNodeTreeWalker != null) { _delegateNodeTreeWalker.clearChildNodes(); } } // PositionAware implements ------------------------------------- public void setSystemID(String systemID) { getNodeTreeWalker().setSystemID(systemID); } public String getSystemID() { return getNodeTreeWalker().getSystemID(); } public void setLineNumber(int lineNumber) { getNodeTreeWalker().setLineNumber(lineNumber); } public int getLineNumber() { return getNodeTreeWalker().getLineNumber(); } public void setOnTemplate(boolean onTemplate) { getNodeTreeWalker().setOnTemplate(onTemplate); } public boolean isOnTemplate() { return getNodeTreeWalker().isOnTemplate(); } // NodeReferenceResolverFinder implements ------------------------------------ public NodeReferenceResolver findNodeResolver() { return getNodeTreeWalker().findNodeResolver(); } // for serialize private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { out.defaultWriteObject(); // namespace out.writeUTF(super.toString()); if (getParentSpace() != null && getParentSpace().getClass() == NamespaceImpl.class) { out.writeObject(getParentSpace()); } else { out.writeObject(new Serializable() { private static final long serialVersionUID = 1L; }); } } private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException { in.defaultReadObject(); if (_delegateNodeTreeWalker != null) { _delegateNodeTreeWalker.setOwner(this); } // namespace String currentMappingInfo = in.readUTF(); NamespaceImpl namespace = deserialize(currentMappingInfo); setDefaultNamespaceMapping(namespace.getDefaultNamespaceMapping()); for (Iterator it = namespace.iteratePrefixMapping(false); it.hasNext();) { PrefixMapping mapping = (PrefixMapping) it.next(); addPrefixMapping(mapping.getPrefix(), mapping.getNamespaceURI()); } // parent namespace Object nscheck = in.readObject(); if (nscheck instanceof NamespaceImpl) { setParentSpace((Namespace) nscheck); } findNodeResolver().nodeLoaded(this); } private Object readResolve() { for (Iterator it = iterateChildNode(); it.hasNext();) { NodeTreeWalker child = (NodeTreeWalker) it.next(); child.setParentNode(this); if (child instanceof Namespace) { ((Namespace) child).setParentSpace(this); } } for (Iterator it = iterateAttribute(); it.hasNext();) { NodeAttributeImpl attr = (NodeAttributeImpl) it.next(); attr.setNode(this); } return this; } public String getId() { return _id; } public boolean equals(Object other) { if (other instanceof SpecificationNodeImpl) { SpecificationNodeImpl otherNode = (SpecificationNodeImpl) other; if (getId() != null) { return getId().equals(otherNode.getId()); } } return false; } // support class -------------------------------------------------- protected static class AllCopyToFilter implements CopyToFilter { public boolean accept(NodeObject test) { return true; } } }