/******************************************************************************* * 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.relational; import java.util.List; import org.eclipse.persistence.tools.workbench.mappingsmodel.ProblemConstants; import org.eclipse.persistence.tools.workbench.mappingsmodel.db.MWColumn; import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.relational.MWRelationalClassDescriptor; import org.eclipse.persistence.tools.workbench.mappingsmodel.handles.MWColumnHandle; 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.mapping.MWConverter; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWDirectMapContainerPolicy; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWDirectMapMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWMapping; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWNullConverter; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWObjectTypeConverter; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWSerializedObjectConverter; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWTypeConversionConverter; import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.xml.MWXmlTypeConversionConverter; 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.mappings.DatabaseMapping; import org.eclipse.persistence.mappings.DirectMapMapping; import org.eclipse.persistence.oxm.XMLDescriptor; import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping; public final class MWRelationalDirectMapMapping extends MWRelationalDirectContainerMapping implements MWDirectMapMapping { private MWColumnHandle directKeyColumnHandle; public final static String DIRECT_KEY_COLUMN_PROPERTY = "directKeyColumn"; private volatile MWConverter directKeyConverter; private MWDirectMapContainerPolicy containerPolicy; // **************** Constructors ****************************************** /** Default constructor - for TopLink use only */ private MWRelationalDirectMapMapping() { super(); } public MWRelationalDirectMapMapping(MWRelationalClassDescriptor parent, MWClassAttribute attribute, String name) { super(parent, attribute, name); } protected void initialize(Node parent) { super.initialize(parent); this.directKeyColumnHandle = new MWColumnHandle(this, this.buildDirectKeyColumnScrubber()); this.directKeyConverter = new MWNullConverter(this); this.containerPolicy = new MWDirectMapContainerPolicy(this); } // ************** Containment Hierarchy ********** protected void addChildrenTo(List children) { super.addChildrenTo(children); children.add(this.directKeyColumnHandle); children.add(this.directKeyConverter); children.add(this.containerPolicy); } private NodeReferenceScrubber buildDirectKeyColumnScrubber() { return new NodeReferenceScrubber() { public void nodeReferenceRemoved(Node node, MWHandle handle) { MWRelationalDirectMapMapping.this.setDirectKeyColumn(null); } public String toString() { return "MWRelationalDirectMapMapping.buildDirectKeyColumnScrubber()"; } }; } // **************** Morphing ************** public MWDirectMapMapping asMWDirectMapMapping() { return this; } protected void initializeOn(MWMapping newMapping) { newMapping.initializeFromMWRelationalDirectMapMapping(this); } // **************** MWQueryable interface *********************** public String iconKey() { return "mapping.directMap"; } // **************** Direct Key Column ****************** public MWColumn getDirectKeyColumn() { return this.directKeyColumnHandle.getColumn(); } public void setDirectKeyColumn(MWColumn directKeyColumn) { checkColumn(directKeyColumn); Object old = this.directKeyColumnHandle.getColumn(); this.directKeyColumnHandle.setColumn(directKeyColumn); firePropertyChanged(DIRECT_KEY_COLUMN_PROPERTY, old, directKeyColumn); } protected void setDirectFieldsNull() { super.setDirectFieldsNull(); setDirectKeyColumn(null); } // **************** Direct Key Converter ****************** public MWConverter getDirectKeyConverter() { return this.directKeyConverter; } public MWNullConverter setNullDirectKeyConverter() { MWNullConverter nullConverter = new MWNullConverter(this); this.setDirectKeyConverter(nullConverter); return nullConverter; } public MWObjectTypeConverter setObjectTypeDirectKeyConverter() { MWObjectTypeConverter objectTypeConverter = new MWObjectTypeConverter(this); this.setDirectKeyConverter(objectTypeConverter); return objectTypeConverter; } public MWSerializedObjectConverter setSerializedObjectDirectKeyConverter() { MWSerializedObjectConverter serializedObjectConverter = new MWSerializedObjectConverter(this); this.setDirectKeyConverter(serializedObjectConverter); return serializedObjectConverter; } public MWTypeConversionConverter setTypeConversionDirectKeyConverter() { MWTypeConversionConverter typeConversionConverter = new MWXmlTypeConversionConverter(this); this.setDirectKeyConverter(typeConversionConverter); return typeConversionConverter; } private void setDirectKeyConverter(MWConverter newConverter) { MWConverter oldConverter = this.directKeyConverter; this.directKeyConverter = newConverter; newConverter.setParent(this); // This step only important when morphing the mapping this.firePropertyChanged(DIRECT_KEY_CONVERTER_PROPERTY, oldConverter, newConverter); } // **************** Container policy ************************************** public MWDirectMapContainerPolicy getContainerPolicy() { return this.containerPolicy; } protected MWClass conatinerPolicyClass() { return getContainerPolicy().getDefaultingContainerClass().getContainerClass(); } // **************** MWRelationalDirectContainerMapping implementation ************** protected int automapNonPrimaryKeyColumnsSize() { return 2; // key and value columns } //************** Problem Handling ********** protected void addProblemsTo(List newProblems) { super.addProblemsTo(newProblems); this.checkDirectKeyColumn(newProblems); } private void checkDirectKeyColumn(List newProblems) { if (this.parentDescriptorIsAggregate()) { return; } if (this.getDirectKeyColumn() == null) { newProblems.add(this.buildProblem(ProblemConstants.MAPPING_DIRECT_KEY_FIELD_NOT_SPECIFIED)); } } // **************** Runtime Conversion ****************** protected DatabaseMapping buildRuntimeMapping() { return new DirectMapMapping(); } public DatabaseMapping runtimeMapping() { DirectMapMapping runtimeMapping = (DirectMapMapping) super.runtimeMapping(); runtimeMapping.setContainerPolicy(this.containerPolicy.runtimeContainerPolicy()); if (getDirectKeyColumn() != null) { runtimeMapping.setDirectKeyFieldName(getDirectKeyColumn().qualifiedName()); } if (!MWConverter.NO_CONVERTER.equals(getDirectKeyConverter().getType())) { runtimeMapping.setKeyConverter(getDirectKeyConverter().runtimeConverter(runtimeMapping)); } return runtimeMapping; } // **************** TopLink methods ******************* public static XMLDescriptor buildDescriptor() { XMLDescriptor descriptor = new XMLDescriptor(); descriptor.setJavaClass(MWRelationalDirectMapMapping.class); descriptor.getInheritancePolicy().setParentClass(MWRelationalDirectContainerMapping.class); XMLCompositeObjectMapping directFieldMapping = new XMLCompositeObjectMapping(); directFieldMapping.setAttributeName("directKeyColumnHandle"); directFieldMapping.setGetMethodName("getDirectKeyColumnHandleForTopLink"); directFieldMapping.setSetMethodName("setDirectKeyColumnHandleForTopLink"); directFieldMapping.setReferenceClass(MWColumnHandle.class); directFieldMapping.setXPath("direct-key-column-handle"); descriptor.addMapping(directFieldMapping); XMLCompositeObjectMapping converterMapping = new XMLCompositeObjectMapping(); converterMapping.setReferenceClass(MWConverter.class); converterMapping.setAttributeName("directKeyConverter"); converterMapping.setGetMethodName("getDirectKeyConverterForTopLink"); converterMapping.setSetMethodName("setDirectKeyConverterForTopLink"); converterMapping.setXPath("direct-key-converter"); descriptor.addMapping(converterMapping); XMLCompositeObjectMapping containerPolicyMapping = new XMLCompositeObjectMapping(); containerPolicyMapping.setAttributeName("containerPolicy"); containerPolicyMapping.setReferenceClass(MWDirectMapContainerPolicy.class); containerPolicyMapping.setXPath("container-policy"); descriptor.addMapping(containerPolicyMapping); return descriptor; } private MWColumnHandle getDirectKeyColumnHandleForTopLink() { return (this.directKeyColumnHandle.getColumn() == null) ? null : this.directKeyColumnHandle; } private void setDirectKeyColumnHandleForTopLink(MWColumnHandle directKeyColumnHandle) { NodeReferenceScrubber scrubber = this.buildDirectKeyColumnScrubber(); this.directKeyColumnHandle = ((directKeyColumnHandle == null) ? new MWColumnHandle(this, scrubber) : directKeyColumnHandle.setScrubber(scrubber)); } private MWConverter getDirectKeyConverterForTopLink() { return (this.directKeyConverter == null) ? null : this.directKeyConverter.getValueForTopLink(); } private void setDirectKeyConverterForTopLink(MWConverter converter) { this.directKeyConverter = (converter == null) ? new MWNullConverter(this) : converter; } }