/******************************************************************************* * 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.mapping; import java.util.HashSet; import java.util.List; import org.eclipse.persistence.tools.workbench.mappingsmodel.MWModel; import org.eclipse.persistence.tools.workbench.mappingsmodel.ProblemConstants; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWDescriptor; import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.MWClassHandle; import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.MWHandle; import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.MWHandle.NodeReferenceScrubber; import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWClass; import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWClassAttribute; import org.eclipse.persistence.tools.workbench.utility.node.Node; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.indirection.IndirectSet; import org.eclipse.persistence.internal.queries.CollectionContainerPolicy; import org.eclipse.persistence.internal.queries.ContainerPolicy; import org.eclipse.persistence.oxm.XMLDescriptor; import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping; import org.eclipse.persistence.oxm.mappings.XMLDirectMapping; public final class MWSetContainerPolicy extends MWModel implements MWContainerPolicy { private DefaultingContainerClass containerClass; private boolean usesSorting; // only used with sorting private MWClassHandle comparatorClass; // **************** Static methods **************** public static XMLDescriptor buildDescriptor() { XMLDescriptor descriptor = new XMLDescriptor(); descriptor.setJavaClass(MWSetContainerPolicy.class); descriptor.getInheritancePolicy().setParentClass(MWContainerPolicy.MWContainerPolicyRoot.class); XMLCompositeObjectMapping containerClassMapping = new XMLCompositeObjectMapping(); containerClassMapping.setAttributeName("containerClass"); containerClassMapping.setReferenceClass(DefaultingContainerClass.class); containerClassMapping.setXPath("container-class"); descriptor.addMapping(containerClassMapping); XMLDirectMapping usesSortingMapping = new XMLDirectMapping(); usesSortingMapping.setAttributeName("usesSorting"); usesSortingMapping.setXPath("uses-sorting/text()"); usesSortingMapping.setNullValue(Boolean.FALSE); descriptor.addMapping(usesSortingMapping); XMLCompositeObjectMapping comparatorClassMapping = new XMLCompositeObjectMapping(); comparatorClassMapping.setAttributeName("comparatorClass"); comparatorClassMapping.setSetMethodName("setComparatorClassHandleForTopLink"); comparatorClassMapping.setGetMethodName("getComparatorClassHandleForTopLink"); comparatorClassMapping.setReferenceClass(MWClassHandle.class); comparatorClassMapping.setXPath("comparator-class-handle"); descriptor.addMapping(comparatorClassMapping); return descriptor; } public static XMLDescriptor legacy60BuildDescriptor() { XMLDescriptor descriptor = MWModel.legacy60BuildStandardDescriptor(); descriptor.setJavaClass(MWSetContainerPolicy.class); descriptor.getInheritancePolicy().setParentClass(MWContainerPolicy.MWContainerPolicyRoot.class); XMLCompositeObjectMapping containerClassMapping = new XMLCompositeObjectMapping(); containerClassMapping.setAttributeName("containerClass"); containerClassMapping.setReferenceClass(DefaultingContainerClass.class); containerClassMapping.setXPath("container-class"); descriptor.addMapping(containerClassMapping); return descriptor; } // ********** constructors ********** /** * Default constructor - for TopLink use only. */ private MWSetContainerPolicy() { super(); } public MWSetContainerPolicy(MWContainerMapping parent) { super(parent); } protected void initialize(Node parent) { super.initialize(parent); this.containerClass = new DefaultingContainerClass(this); this.comparatorClass = new MWClassHandle(this, buildComparatorTypeScrubber()); } private NodeReferenceScrubber buildComparatorTypeScrubber() { return new NodeReferenceScrubber() { public void nodeReferenceRemoved(Node node, MWHandle handle) { setComparatorClass(null); } public String toString() { return "MWSetContainerPolicy.buildComparatorTypeScrubber()"; } }; } protected void addChildrenTo(List list) { super.addChildrenTo(list); list.add(this.containerClass); list.add(this.comparatorClass); } // ************ accessors *************** public DefaultingContainerClass getDefaultingContainerClass() { return this.containerClass; } private MWContainerMapping getContainerMapping() { return (MWContainerMapping) getParent(); } private MWMapping getMapping() { return (MWMapping) getParent(); } private MWClassAttribute getInstanceVariable() { return ((MWMapping) getParent()).getInstanceVariable(); } public boolean usesSorting() { return usesSorting; } public void setUsesSorting(boolean sort) { boolean oldValue = this.usesSorting; this.usesSorting = sort; firePropertyChanged(SORT_PROPERTY, oldValue, this.usesSorting); } public MWClass getComparatorClass() { return comparatorClass.getType(); } public void setComparatorClass(MWClass comparatorClass) { MWClass oldValue = this.comparatorClass.getType(); this.comparatorClass.setType(comparatorClass); firePropertyChanged(COMPARATOR_CLASS_PROPERTY, oldValue, this.comparatorClass.getType()); } // **************** Behavior ********************************************** public MWClass defaultContainerClass() { if (this.getContainerMapping().usesTransparentIndirection()) { return this.defaultIndirectContainerClass(); } MWClassAttribute instanceVariable = this.getInstanceVariable(); MWClass attributeContainerType; if (instanceVariable.isValueHolder()) { attributeContainerType = getInstanceVariable().getValueType(); } else { attributeContainerType = getInstanceVariable().getType(); } if (attributeContainerType.isAssignableToSet()) { if (attributeContainerType.isInstantiable()) { return attributeContainerType; } } return typeFor(HashSet.class); } private MWClass defaultIndirectContainerClass() { return typeFor(IndirectSet.class); } public void referenceDescriptorChanged(MWDescriptor newReferenceDescriptor) { //nothing to do } // ************** Problem Handling **************** protected void addProblemsTo(List currentProblems) { super.addProblemsTo(currentProblems); MWClass containerType = this.getDefaultingContainerClass().getContainerClass(); if ((containerType != null) && ! containerType.mightBeAssignableToSet()) { currentProblems.add(this.buildProblem(ProblemConstants.MAPPING_CONTAINER_CLASS_NOT_SET)); } if (this.usesSorting() && containerType != null && !containerType.mightBeAssignableToSortedSet()) { currentProblems.add(this.buildProblem(ProblemConstants.MAPPING_CONTAINER_CLASS_NOT_SORTED_SET)); } MWClass comparatorType = this.getComparatorClass(); if (this.usesSorting() && comparatorType == null) { currentProblems.add(this.buildProblem(ProblemConstants.USES_SORTING_NO_COMPARATOR_CLASS_SELECTED)); } if (this.usesSorting() && comparatorType != null && !comparatorType.mightBeAssignableToComparator()) { currentProblems.add(this.buildProblem(ProblemConstants.COMPARATOR_CLASS_NOT_COMPARATOR)); } } // **************** Runtime conversion ***************** public ContainerPolicy runtimeContainerPolicy() { return new CollectionContainerPolicy(getDefaultingContainerClass().getContainerClass().getName()); } // **************** TopLink methods ************************ @Override protected void legacy60PostBuild(DescriptorEvent event) { super.legacy60PostBuild(event); this.comparatorClass = new MWClassHandle(this, buildComparatorTypeScrubber()); } /** * check for null */ private MWClassHandle getComparatorClassHandleForTopLink() { return (this.comparatorClass.getType() == null) ? null : this.comparatorClass; } private void setComparatorClassHandleForTopLink(MWClassHandle handle) { NodeReferenceScrubber scrubber = this.buildComparatorTypeScrubber(); this.comparatorClass = ((handle == null) ? new MWClassHandle(this, scrubber) : handle.setScrubber(scrubber)); } }