/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.mappingsmodel.handles; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.persistence.tools.workbench.mappingsmodel.MWNode; import org.eclipse.persistence.tools.workbench.mappingsmodel.project.xml.MWXmlProject; import org.eclipse.persistence.tools.workbench.mappingsmodel.schema.MWNamedSchemaComponent; import org.eclipse.persistence.tools.workbench.mappingsmodel.schema.MWXmlSchema; import org.eclipse.persistence.tools.workbench.mappingsmodel.schema.MWXmlSchemaRepository; import org.eclipse.persistence.tools.workbench.utility.node.Node; import org.eclipse.persistence.oxm.XMLDescriptor; import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping; public final class MWNamedSchemaComponentHandle extends MWHandle { /** * This is the actual component. * It is built from the schema and path information below. */ private volatile MWNamedSchemaComponent component; /** * The schema and qname path are transient. They * are used only to hold their values until postProjectBuild() * is called and we can resolve the actual component. * We do not keep these in synch with the component itself because * we cannot know when the components in the path have been renamed etc. */ private volatile String schemaName; private List qNamePath; // ********** constructors ********** /** default constructor - for TopLink use only */ private MWNamedSchemaComponentHandle() { super(); } public MWNamedSchemaComponentHandle(MWNode parent, NodeReferenceScrubber scrubber) { super(parent, scrubber); } public MWNamedSchemaComponentHandle(MWNode parent, MWNamedSchemaComponent component, NodeReferenceScrubber scrubber) { super(parent, scrubber); this.component = component; } // ********** instance methods ********** private MWXmlSchemaRepository getSchemaRepository() { return ((MWXmlProject) getProject()).getSchemaRepository(); } public MWNamedSchemaComponent getComponent() { return this.component; } public void setComponent(MWNamedSchemaComponent component) { this.component = component; } protected Node node() { return getComponent(); } public MWNamedSchemaComponentHandle setScrubber(NodeReferenceScrubber scrubber) { this.setScrubberInternal(scrubber); return this; } public void resolveMetadataHandles() { super.resolveMetadataHandles(); if (this.schemaName != null && ! this.qNamePath.isEmpty()) { MWXmlSchema schema = this.getSchemaRepository().getSchema(this.schemaName); MWNamedSchemaComponent temp; if (schema != null) { Iterator stream = this.qNamePath.iterator(); QName qName = (QName) stream.next(); temp = schema.component(qName); while (stream.hasNext()) { qName = (QName) stream.next(); temp = temp.nestedNamedComponent(qName); } this.component = temp; } } // Ensure schemaName and complexTypeQName are not used by setting them to null.... // If the XML is corrupt and only one of these attributes is populated, // this will cause the populated attribute to be cleared out if the // objects are rewritten. this.schemaName = null; this.qNamePath = null; } /** * Override to delegate comparison to the element itself. * If the handles being compared are in a collection that is being sorted, * NEITHER field should be null. */ public int compareTo(Object o) { return this.component.compareTo(((MWNamedSchemaComponentHandle) o).component); } public void toString(StringBuffer sb) { sb.append(this.component.getName()); } // ********** TopLink methods ********** public static XMLDescriptor buildDescriptor() { XMLDescriptor descriptor = new XMLDescriptor(); descriptor.setJavaClass(MWNamedSchemaComponentHandle.class); descriptor.addDirectMapping("schemaName", "getSchemaNameForTopLink", "setSchemaNameForTopLink", "schema/text()"); XMLCompositeCollectionMapping qNamePathMapping = new XMLCompositeCollectionMapping(); qNamePathMapping.setAttributeName("qNamePath"); qNamePathMapping.setReferenceClass(QName.class); qNamePathMapping.setGetMethodName("getQNamePathForTopLink"); qNamePathMapping.setSetMethodName("setQNamePathForTopLink"); qNamePathMapping.setXPath("qname-path/qname"); descriptor.addMapping(qNamePathMapping); return descriptor; } private String getSchemaNameForTopLink(){ return (this.component == null) ? null : this.component.getSchema().getName(); } private void setSchemaNameForTopLink(String schemaName) { this.schemaName = schemaName; } private List getQNamePathForTopLink() { List path = new ArrayList(); for (MWNamedSchemaComponent temp = this.component; temp != null; ) { path.add(0, new QName(temp)); temp = temp.parentNamedComponent(); } return path; } private void setQNamePathForTopLink(List path) { this.qNamePath = path; } }