/*******************************************************************************
* 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.relational;
import java.util.Collections;
import java.util.List;
import org.eclipse.persistence.tools.workbench.mappingsmodel.MWModel;
import org.eclipse.persistence.tools.workbench.mappingsmodel.MWQueryKey;
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.MWDescriptor;
import org.eclipse.persistence.tools.workbench.mappingsmodel.descriptor.MWMappingDescriptor;
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.relational.AggregateFieldDescription;
import org.eclipse.persistence.tools.workbench.mappingsmodel.mapping.relational.AggregateRuntimeFieldNameGenerator;
import org.eclipse.persistence.tools.workbench.mappingsmodel.query.MWQueryable;
import org.eclipse.persistence.tools.workbench.utility.CollectionTools;
import org.eclipse.persistence.tools.workbench.utility.filters.Filter;
import org.eclipse.persistence.tools.workbench.utility.node.Node;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
public final class MWUserDefinedQueryKey extends MWModel
implements MWQueryKey, MWQueryable, AggregateRuntimeFieldNameGenerator {
private volatile String name;
private MWColumnHandle columnHandle;
public final static String COLUMN_PROPERTY = "column";
// ********** Constructors **********
/**
* Default constructor - for TopLink use only.
*/
private MWUserDefinedQueryKey() {
super();
}
MWUserDefinedQueryKey(String name, MWRelationalClassDescriptor parent, MWColumn column) {
this(name, parent);
this.columnHandle.setColumn(column);
}
MWUserDefinedQueryKey(String name, MWRelationalClassDescriptor parent) {
super(parent);
initialize(name);
}
// ********** Initialization **********
/**
* initialize persistent state
*/
protected void initialize(Node parent) {
super.initialize(parent);
this.columnHandle = new MWColumnHandle(this, this.buildColumnScrubber());
}
private void initialize(String qkName) {
checkName(qkName);
this.name = qkName;
}
protected void checkName(String qkName) {
if (qkName == null || qkName == "") {
throw new IllegalArgumentException("MWUserDefinedQueryKey name cannot be null");
}
getDescriptor().checkQueryKeyName(qkName);
}
// ********** Containment hierarchy **********
protected void addChildrenTo(List children) {
super.addChildrenTo(children);
children.add(this.columnHandle);
}
private NodeReferenceScrubber buildColumnScrubber() {
return new NodeReferenceScrubber() {
public void nodeReferenceRemoved(Node node, MWHandle handle) {
MWUserDefinedQueryKey.this.setColumn(null);
}
public String toString() {
return "MWUserDefinedQueryKey.buildColumnScrubber()";
}
};
}
// ********** MWQueryable implementation **********
public boolean allowsChildren() {
return false;
}
public boolean allowsOuterJoin() {
return allowsChildren();
}
public MWMappingDescriptor getParentDescriptor() {
return getDescriptor();
}
public List subQueryableElements(Filter queryableFilter) {
return Collections.EMPTY_LIST;
}
public MWQueryable subQueryableElementAt(int index, Filter queryableFilter) {
return null;
}
public boolean isLeaf(Filter queryableFilter) {
return true;
}
public String iconKey() {
return "queryKey.userDefined";
}
public boolean usesAnyOf() {
return false;
}
public boolean isTraversableForReadAllQueryOrderable() {
return true;
}
public boolean isValidForReadAllQueryOrderable() {
return true;
}
public boolean isTraversableForBatchReadAttribute() {
return false;
}
public boolean isValidForBatchReadAttribute() {
return false;
}
public boolean isTraversableForJoinedAttribute() {
return false;
}
public boolean isValidForJoinedAttribute() {
return false;
}
public boolean isValidForReportQueryAttribute() {
return true;
}
public boolean isTraversableForReportQueryAttribute() {
return true;
}
public boolean isTraversableForQueryExpression() {
return true;
}
public boolean isValidForQueryExpression() {
return true;
}
// ********** MWQueryKey implementation **********
public String getName() {
return this.name;
}
public void setName(String name) {
checkName(name);
Object old = this.name;
this.name = name;
this.firePropertyChanged(NAME_PROPERTY, old, name);
if (this.attributeValueHasChanged(old, name)) {
this.getProject().nodeRenamed(this);
}
}
public boolean isAutoGenerated() {
return false;
}
public MWRelationalClassDescriptor getDescriptor() {
return (MWRelationalClassDescriptor) this.getParent();
}
public MWColumn getColumn() {
return this.columnHandle.getColumn();
}
public void setColumn(MWColumn column) {
Object old = this.columnHandle.getColumn();
this.columnHandle.setColumn(column);
this.firePropertyChanged(COLUMN_PROPERTY, old, column);
}
//************* AggregateRuntimeFieldNameGenerator implementation ************
public String fieldNameForRuntime() {
return "QUERY_KEY " + getName();
}
public AggregateFieldDescription fullFieldDescription() {
return new AggregateFieldDescription() {
public String getMessageKey() {
return "AGGREGATE_FIELD_DESCRIPTION_FOR_USER_DEFINED_QUERY_KEY";
}
public Object[] getMessageArguments() {
return new Object[] {getName()};
}
};
}
public boolean fieldIsWritten() {
return false;
}
public MWDescriptor owningDescriptor() {
return (MWDescriptor) this.getParent();
}
//*********** Problem Handling *********
/**
* Check for any problems and add them to the specified collection.
*/
protected void addProblemsTo(List newProblems) {
super.addProblemsTo(newProblems);
this.checkColumns(newProblems);
}
private void checkColumns(List currentProblems) {
if (((MWRelationalDescriptor) this.getParentDescriptor()).isAggregateDescriptor()) {
return;
}
if (this.getColumn() == null) {
currentProblems.add(this.buildProblem(ProblemConstants.DESCRIPTOR_QUERY_KEY_NO_COLUMN_SPECIFIED, this.getName()));
}
else if ( ! CollectionTools.contains(((MWTableDescriptor) this.getParentDescriptor()).allAssociatedColumns(), this.getColumn())) {
currentProblems.add(this.buildProblem(ProblemConstants.DESCRIPTOR_QUERY_KEY_INVALID_COLUMN, this.getName()));
}
}
// ********** Display methods **********
public String displayString() {
return this.getName();
}
public void toString(StringBuffer sb) {
sb.append("field=");
if (getColumn() == null) {
sb.append("null");
}
else {
getColumn().toString(sb);
}
}
// ********** TopLink methods *********
public static XMLDescriptor buildDescriptor() {
XMLDescriptor descriptor = new XMLDescriptor();
descriptor.setJavaClass(MWUserDefinedQueryKey.class);
descriptor.addDirectMapping("name", "name/text()");
XMLCompositeObjectMapping columnHandleMapping = new XMLCompositeObjectMapping();
columnHandleMapping.setAttributeName("columnHandle");
columnHandleMapping.setGetMethodName("getColumnHandleForTopLink");
columnHandleMapping.setSetMethodName("setColumnHandleForTopLink");
columnHandleMapping.setReferenceClass(MWColumnHandle.class);
columnHandleMapping.setXPath("column-handle");
descriptor.addMapping(columnHandleMapping);
return descriptor;
}
private MWColumnHandle getColumnHandleForTopLink() {
return (this.columnHandle.getColumn() == null) ? null : this.columnHandle;
}
private void setColumnHandleForTopLink(MWColumnHandle handle) {
NodeReferenceScrubber scrubber = this.buildColumnScrubber();
this.columnHandle = ((handle == null) ? new MWColumnHandle(this, scrubber) : handle.setScrubber(scrubber));
}
}