/*******************************************************************************
* 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.descriptor.xml;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.eis.EISDescriptor;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.tools.workbench.mappingsmodel.MWDataField;
import org.eclipse.persistence.tools.workbench.mappingsmodel.ProblemConstants;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWAdvancedPropertyAdditionException;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWAdvancedPropertyRemovalException;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWDescriptor;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWDescriptorInterfaceAliasPolicy;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWDescriptorPolicy;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWInterfaceAliasDescriptor;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWNullDescriptorPolicy;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWReturningPolicy;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWTransactionalDescriptor;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWTransactionalPolicy;
import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.MWMapping;
import org.eclipse.persistence.tools.workbench.mappingsmodel.meta.MWClass;
import org.eclipse.persistence.tools.workbench.mappingsmodel.project.MWProjectDefaultsPolicy;
import org.eclipse.persistence.tools.workbench.mappingsmodel.project.xml.MWEisProject;
import org.eclipse.persistence.tools.workbench.mappingsmodel.query.MWQueryManager;
import org.eclipse.persistence.tools.workbench.utility.CollectionTools;
import org.eclipse.persistence.tools.workbench.utility.iterators.TransformationIterator;
import org.eclipse.persistence.tools.workbench.utility.node.Node;
public final class MWRootEisDescriptor extends MWEisDescriptor
implements MWTransactionalDescriptor, MWInterfaceAliasDescriptor {
private volatile MWDescriptorPolicy returningPolicy;
private volatile MWDescriptorPolicy interfaceAliasPolicy;
public final static String INTERFACE_ALIAS_POLICY_PROPERTY = "interfaceAliasPolicy";
// **************** Static methods ************
public static XMLDescriptor buildDescriptor() {
XMLDescriptor descriptor = new XMLDescriptor();
descriptor.setJavaClass(MWRootEisDescriptor.class);
descriptor.getInheritancePolicy().setParentClass(MWXmlDescriptor.class);
XMLCompositeObjectMapping returningPolicyMapping = new XMLCompositeObjectMapping();
returningPolicyMapping.setAttributeName("returningPolicy");
returningPolicyMapping.setReferenceClass(MWEisReturningPolicy.class);
returningPolicyMapping.setSetMethodName("setReturningPolicyForTopLink");
returningPolicyMapping.setGetMethodName("getReturningPolicyForTopLink");
returningPolicyMapping.setXPath("returning-policy");
descriptor.addMapping(returningPolicyMapping);
XMLCompositeObjectMapping interfaceAliasPolicyMapping = new XMLCompositeObjectMapping();
interfaceAliasPolicyMapping.setAttributeName("interfaceAliasPolicy");
interfaceAliasPolicyMapping.setReferenceClass(MWDescriptorInterfaceAliasPolicy.class);
interfaceAliasPolicyMapping.setSetMethodName("setInterfaceAliasPolicyForTopLink");
interfaceAliasPolicyMapping.setGetMethodName("getInterfaceAliasPolicyForTopLink");
interfaceAliasPolicyMapping.setXPath("interface-alias-policy");
descriptor.addMapping(interfaceAliasPolicyMapping);
return descriptor;
}
// **************** Constructors ************
private MWRootEisDescriptor() {
super();
}
public MWRootEisDescriptor(MWEisProject project, MWClass type, String name) {
super(project, type, name);
}
protected void initialize(Node parent) {
super.initialize(parent);
setInitialDefaultRootElement();
this.returningPolicy = new MWNullDescriptorPolicy(this);
this.interfaceAliasPolicy = new MWNullDescriptorPolicy(this);
}
protected void addChildrenTo(List children) {
super.addChildrenTo(children);
children.add(this.interfaceAliasPolicy);
children.add(this.returningPolicy);
}
protected MWTransactionalPolicy buildDefaultTransactionalPolicy() {
return new MWEisTransactionalPolicy(this);
}
public MWRootEisDescriptor asRootEisDescriptor() {
return this;
}
public void applyAdvancedPolicyDefaults(MWProjectDefaultsPolicy defaultsPolicy) {
defaultsPolicy.applyAdvancedPolicyDefaults(this);
}
// **************** Convenience ************
public MWQueryManager getQueryManager() {
return getTransactionalPolicy().getQueryManager();
}
public boolean isRootDescriptor() {
return true;
}
// **************** Primary key policy ************************************
public MWXmlPrimaryKeyPolicy primaryKeyPolicy() {
return ((MWEisTransactionalPolicy) this.getTransactionalPolicy()).getPrimaryKeyPolicy();
}
// **************** Interface Alias Policy API ******************************
public void addInterfaceAliasPolicy() throws MWAdvancedPropertyAdditionException
{
if (interfaceAliasPolicy.isActive())
{
throw new MWAdvancedPropertyAdditionException(INTERFACE_ALIAS_POLICY_PROPERTY, "policy already exists on descriptor");
}
else
{
setInterfaceAliasPolicy(new MWDescriptorInterfaceAliasPolicy(this));
}
}
public void removeInterfaceAliasPolicy()
{
if (interfaceAliasPolicy.isActive())
{
setInterfaceAliasPolicy(new MWNullDescriptorPolicy(this));
}
else
{
throw new MWAdvancedPropertyRemovalException(INTERFACE_ALIAS_POLICY_PROPERTY, "policy does not exist on the descriptor");
}
}
public MWDescriptorPolicy getInterfaceAliasPolicy()
{
return interfaceAliasPolicy;
}
private MWDescriptorInterfaceAliasPolicy getInterfaceAliasPolicyForTopLink()
{
return (MWDescriptorInterfaceAliasPolicy)interfaceAliasPolicy.getPersistedPolicy();
}
protected void setInterfaceAliasPolicy(MWDescriptorPolicy interfaceAliasPolicy) {
Object old = this.interfaceAliasPolicy;
this.interfaceAliasPolicy = interfaceAliasPolicy;
firePropertyChanged(INTERFACE_ALIAS_POLICY_PROPERTY, old, this.interfaceAliasPolicy);
}
private void setInterfaceAliasPolicyForTopLink(MWDescriptorInterfaceAliasPolicy interfaceAliasPolicy)
{
if (interfaceAliasPolicy == null)
{
this.interfaceAliasPolicy = new MWNullDescriptorPolicy(this);
}
else
{
this.interfaceAliasPolicy = interfaceAliasPolicy;
}
}
/** - returns an iterator on all mappings that map to the given xpath */
private Iterator mappingsForXpath(String xpath) {
Collection mappings = new ArrayList();
for (Iterator stream = this.mappings(); stream.hasNext(); ) {
MWMapping mapping = (MWMapping) stream.next();
//TODO addWrittenFieldsTo(Collection) is not fully implemented in the mappings model
Collection writtenFields = new ArrayList();
mapping.addWrittenFieldsTo(writtenFields);
if (writtenFields.contains(xpath)) {
mappings.add(mapping);
}
}
return mappings.iterator();
}
// - returns an iterator on the attributes mapped by all mappings obtained by
// getPrimaryKeyMappings()
public Iterator primaryKeyAttributes() {
return new TransformationIterator(this.primaryKeyMappings()) {
protected Object transform(Object next) {
return ((MWMapping) next).getInstanceVariable();
}
};
}
// - returns an iterator on all mappings in this descriptor that map to primary key fields,
// plus all mappings in this descriptor's superdescriptors that do the same
public Iterator primaryKeyMappings() {
Collection pkMappings = new Vector();
for (Iterator stream = primaryKeyPolicy().primaryKeyXpaths(); stream.hasNext(); ) {
CollectionTools.addAll(pkMappings, mappingsForXpath((String) stream.next()));
}
MWDescriptor parentDescriptor = getInheritancePolicy().getParentDescriptor();
//TODO remove the instanceof put the primaryKeyMapping() api on MWEisDescriptor and just return an empty collection
if (parentDescriptor != null && parentDescriptor instanceof MWRootEisDescriptor) {
CollectionTools.addAll(pkMappings, ((MWRootEisDescriptor) parentDescriptor).primaryKeyMappings());
}
return pkMappings.iterator();
}
// ********** MWReturningPolicy API**********
public MWDescriptorPolicy getReturningPolicy() {
return this.returningPolicy;
}
private void setReturningPolicy(MWDescriptorPolicy returningPolicy) {
Object old = this.returningPolicy;
this.returningPolicy = returningPolicy;
firePropertyChanged( RETURNING_POLICY_PROPERTY, old, returningPolicy);
}
public void addReturningPolicy() throws MWAdvancedPropertyAdditionException {
if(this.returningPolicy.isActive()) {
throw new MWAdvancedPropertyAdditionException( RETURNING_POLICY_PROPERTY, "policy already exists on descriptor");
}
else {
setReturningPolicy(new MWEisReturningPolicy(this));
}
}
public void removeReturningPolicy() {
if(this.returningPolicy.isActive()) {
getReturningPolicy().dispose();
setReturningPolicy(new MWNullDescriptorPolicy(this));
}
else {
throw new MWAdvancedPropertyRemovalException( RETURNING_POLICY_PROPERTY, "policy does not exist on the descriptor");
}
}
public boolean supportsReturningPolicy() {
return true;
}
public boolean supportsCachingPolicy() {
return true;
}
//************* Problem Handling *************
/** Check for any problems and add them to the specified collection. */
protected void addProblemsTo(List newProblems) {
super.addProblemsTo(newProblems);
this.checkPrimaryKeysSpecified(newProblems);
this.checkWritableMappingsForPrimaryKeys(newProblems);
}
private void checkPrimaryKeysSpecified(List newProblems) {
boolean hasParent = getInheritancePolicy().getParentDescriptor() != null;
if (this.isRootDescriptor()
&& ! hasParent
&& (this.getSchemaContext() != null)
&& (((MWEisTransactionalPolicy) this.getTransactionalPolicy()).getPrimaryKeyPolicy().primaryKeysSize() == 0))
{
newProblems.add(this.buildProblem(ProblemConstants.EIS_DESCRIPTOR_NO_PRIMARY_KEYS_SPECIFIED));
}
}
private void checkWritableMappingsForPrimaryKeys(List newProblems) {
if (((MWEisTransactionalPolicy)getTransactionalPolicy()).getPrimaryKeyPolicy().primaryKeysSize() > 0) {
for (Iterator stream = ((MWEisTransactionalPolicy)getTransactionalPolicy()).getPrimaryKeyPolicy().primaryKeys(); stream.hasNext(); ) {
if (this.writableMappingsForField((MWDataField)stream.next()).isEmpty()) {
newProblems.add(this.buildProblem(ProblemConstants.EIS_ROOT_DESCRIPTOR_NO_WRITABLE_MAPPINGS_FOR_PRIMARY_KEYS));
}
}
}
}
// ************** Runtime conversion *****************
public ClassDescriptor buildRuntimeDescriptor() {
EISDescriptor runtimeDescriptor = (EISDescriptor) super.buildRuntimeDescriptor();
this.returningPolicy.adjustRuntimeDescriptor(runtimeDescriptor);
this.interfaceAliasPolicy.adjustRuntimeDescriptor(runtimeDescriptor);
return runtimeDescriptor;
}
// ************** TopLink only methods *****************
private MWReturningPolicy getReturningPolicyForTopLink() {
return (MWReturningPolicy) this.returningPolicy.getPersistedPolicy();
}
private void setReturningPolicyForTopLink(MWReturningPolicy returningPolicy) {
if (returningPolicy == null) {
this.returningPolicy = new MWNullDescriptorPolicy(this);
}
else {
this.returningPolicy = returningPolicy;
}
}
}