blob: ada0c94a8d5470b5371e2e4a10bdaf23fa2a6272 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.databinding.sdo;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.xml.namespace.QName;
import org.apache.tuscany.sca.databinding.TransformationContext;
import org.apache.tuscany.sca.databinding.TransformationException;
import org.apache.tuscany.sca.databinding.util.DataTypeHelper;
import org.apache.tuscany.sca.databinding.util.LRUCache;
import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.interfacedef.util.XMLType;
import org.apache.tuscany.sdo.api.SDOUtil;
import commonj.sdo.DataObject;
import commonj.sdo.Type;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.TypeHelper;
import commonj.sdo.impl.HelperProvider;
/**
* Helper class to get TypeHelper from the context
*
* @version $Rev$ $Date$
*/
public final class SDOContextHelper {
private static final LRUCache<Object, HelperContext> cache = new LRUCache<Object, HelperContext>(1024);
private SDOContextHelper() {
}
public static HelperContext getHelperContext(TransformationContext context, boolean source) {
if (context == null) {
return getDefaultHelperContext();
}
HelperContext helperContext = null;
Operation op = source ? context.getSourceOperation() : context.getTargetOperation();
if (op == null) {
DataType<?> dt = source ? context.getSourceDataType() : context.getTargetDataType();
helperContext = dt.getMetaData(HelperContext.class);
if (helperContext != null) {
return helperContext;
}
helperContext = SDOUtil.createHelperContext();
boolean found = register(helperContext, dt);
if (!found) {
helperContext = getDefaultHelperContext();
}
dt.setMetaData(HelperContext.class, helperContext);
return helperContext;
} else {
return getHelperContext(op);
}
}
public static HelperContext getHelperContext(Operation op) {
if (op == null) {
return getDefaultHelperContext();
}
HelperContext helperContext = op.getInputType().getMetaData(HelperContext.class);
if (helperContext != null) {
return helperContext;
}
// Use the default HelperContext until a type is registered later on
helperContext = getDefaultHelperContext();
/*
List<DataType> dataTypes = DataTypeHelper.getDataTypes(op, false);
boolean found = false;
for (DataType d : dataTypes) {
if (register(helperContext, d)) {
found = true;
}
}
if (!found) {
helperContext = getDefaultHelperContext();
}
*/
op.getInputType().setMetaData(HelperContext.class, helperContext);
return helperContext;
}
/**
* @param helperContext
* @param dataType
* @return
*/
private static boolean register(HelperContext helperContext, DataType dataType) {
if (dataType == null) {
return false;
}
Set<Class<?>> classes = DataTypeHelper.findClasses(dataType);
boolean found = false;
for (Class<?> cls : classes) {
found = register(helperContext, dataType.getPhysical()) || found;
}
return found;
}
/**
* FIXME: [rfeng] This is a hack to get the factory out a SDO class
* @param helperContext
* @param javaType
*/
public static boolean register(HelperContext helperContext, Class javaType) {
if (javaType == null || DataObject.class == javaType) {
return false;
}
try {
Type type = helperContext.getTypeHelper().getType(javaType);
return register(helperContext, type);
} catch (Exception e) {
throw new TransformationException(e);
}
}
public static boolean register(HelperContext helperContext, Type type) {
if (type != null && (!type.isDataType())) {
try {
Method method = type.getClass().getMethod("getEPackage");
Object factory = method.invoke(type, new Object[] {});
method = factory.getClass().getMethod("register", HelperContext.class);
method.invoke(factory, new Object[] {helperContext});
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} else {
return false;
}
}
public static HelperContext getDefaultHelperContext() {
// SDOUtil.createHelperContext();
return HelperProvider.getDefaultContext();
}
public static QName getElement(TransformationContext context) {
if (context == null) {
return SDODataBinding.ROOT_ELEMENT;
}
DataType<?> dataType = context.getTargetDataType();
Object logical = dataType.getLogical();
QName elementName = null;
if (logical instanceof XMLType) {
XMLType xmlType = (XMLType)logical;
QName element = xmlType.getElementName();
if (element != null) {
elementName = element;
}
}
if (elementName == null) {
// Try source type
dataType = context.getSourceDataType();
logical = dataType.getLogical();
if (logical instanceof XMLType) {
XMLType xmlType = (XMLType)logical;
QName element = xmlType.getElementName();
if (element != null) {
elementName = element;
}
}
}
if (elementName != null) {
return elementName;
} else {
return SDODataBinding.ROOT_ELEMENT;
}
}
public static String generateSchema(HelperContext context, Class<?>[] classes) {
TypeHelper typeHelper = context.getTypeHelper();
List<Type> types = new ArrayList<Type>();
for (Class<?> cls : classes) {
Type type = typeHelper.getType(cls);
if (type != null) {
types.add(type);
}
}
return generateSchema(context, types);
}
public static String generateSchema(HelperContext context, List<Type> types) {
// FIXME: SDO throws IllegalArgumentException for types generated from existing XSDs
return context.getXSDHelper().generate(types);
}
}