Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2009-2010, James Leigh and Zepheira LLC Some rights reserved.
* Copyright (c) 2011 Talis Inc., Some rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the openrdf.org nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
package org.openrdf.repository.object.composition.helpers;
import static java.lang.reflect.Modifier.isAbstract;
import static java.lang.reflect.Modifier.isPublic;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.openrdf.annotations.InstancePrivate;
import org.openrdf.annotations.Iri;
import org.openrdf.annotations.ParameterTypes;
import org.openrdf.model.vocabulary.OWL;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.object.composition.BehaviourFactory;
import org.openrdf.repository.object.composition.ClassFactory;
import org.openrdf.repository.object.composition.ClassTemplate;
import org.openrdf.repository.object.composition.CodeBuilder;
import org.openrdf.repository.object.composition.MethodBuilder;
import org.openrdf.repository.object.traits.RDFObjectBehaviour;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class takes a collection of roles (interfaces or classes) and uses
* composition to combine this into a single class.
*
* @author James Leigh
*
*/
public class ClassComposer {
public static void calling(Object target, String method, Object[] args) {
if (++count % 512 == 0){
Throwable stack = new Throwable();
StackTraceElement[] trace = stack.getStackTrace();
if(trace.length > 512) {
String string = Arrays.asList(args).toString();
String substring = string.substring(1, string.length() - 1);
logger.warn(target + "<-" + method + "(" + substring + ")", stack);
}
}
}
private static int count;
private static Set special = new HashSet(Arrays.asList(
"groovy.lang.GroovyObject", RDFObjectBehaviour.class.getName()));
private static Logger logger = LoggerFactory.getLogger(ClassComposer.class);
private ClassFactory cp;
private final String className;
private Class> baseClass = Object.class;
private final Set> interfaces;
private final Set allBehaviours;
private Collection methods;
private Map namedMethods;
private Map superMethods = new HashMap();
private Map> behaviours;
private ClassTemplate cc;
public ClassComposer(String className, int size) {
this.className = className;
interfaces = new LinkedHashSet>(size);
allBehaviours = new LinkedHashSet(size);
}
public void setClassFactory(ClassFactory cp) {
this.cp = cp;
}
public void setBaseClass(Class> baseClass) {
this.baseClass = baseClass;
}
public Set> getInterfaces() {
return interfaces;
}
public void addInterface(Class> iface) {
this.interfaces.add(iface);
}
public void addAllBehaviours(
Collection extends BehaviourFactory> factories) {
this.allBehaviours.addAll(factories);
}
public Class> compose() throws Exception {
logger.trace("public class {} extends {}", className, baseClass);
cc = cp.createClassTemplate(className, baseClass);
for (BehaviourFactory behaviours : allBehaviours) {
for (Class> clazz : behaviours.getInterfaces()) {
addInterfaces(clazz);
}
}
for (Class> face : interfaces) {
cc.addInterface(face);
}
behaviours = new HashMap>();
for (BehaviourFactory clazz : allBehaviours) {
addBehaviour(clazz);
for (Method m : clazz.getMethods()) {
if (!isSpecial(m)) {
Set s = behaviours.get(m.getName());
if (s == null) {
s = new HashSet();
behaviours.put(m.getName(), s);
}
s.add(clazz);
}
}
}
Collection all = getAllMethods();
methods = getUniqueMethods(all);
namedMethods = getNamedMethods(all);
for (Method method : methods) {
if (!method.getName().startsWith("_$")) {
boolean bridge = isBridge(method, methods);
implementMethod(method, method.getName(), bridge);
}
}
try {
Class> createdClass = cp.createClass(cc);
for (BehaviourFactory clazz : allBehaviours) {
populateBehaviourField(clazz, createdClass);
}
return createdClass;
} catch (LinkageError e) {
String msg = e.getMessage() + " while composing "
+ baseClass.getSimpleName() + " with " + interfaces;
LinkageError error = new LinkageError(msg);
error.initCause(e);
throw error;
}
}
private void addInterfaces(Class> clazz) {
if (interfaces.contains(clazz))
return;
if (clazz.isInterface()) {
interfaces.add(clazz);
}
Class> superclass = clazz.getSuperclass();
if (superclass != null) {
addInterfaces(superclass);
}
for (Class> face : clazz.getInterfaces()) {
if (isPublic(face.getModifiers()) && !isSpecial(face)) {
addInterfaces(face);
}
}
}
private boolean isSpecial(Class> face) {
return special.contains(face.getName());
}
private Collection getAllMethods() {
List methods = new LinkedList();
for (Class> jc : interfaces) {
for (Method m : jc.getMethods()) {
if (isSpecial(m))
continue;
methods.add(m);
}
}
for (BehaviourFactory factory : allBehaviours) {
for (Method m : factory.getMethods()) {
if (isSpecial(m))
continue;
methods.add(m);
}
}
return methods;
}
private Collection getUniqueMethods(Collection methods) {
Map, Method> map = new HashMap, Method>(methods.size());
for (Method m : methods) {
Class>[] ptypes = getParameterTypes(m);
List list = new ArrayList(ptypes.length + 2);
list.add(m.getName());
list.add(m.getReturnType());
list.addAll(Arrays.asList(ptypes));
if (map.containsKey(list)) {
if (getRank(m) > getRank(map.get(list))) {
map.put(list, m);
}
} else {
map.put(list, m);
}
}
return map.values();
}
private Map getNamedMethods(Collection all) {
Map namedMethods = new HashMap(all.size());
for (Method method : all) {
if (method.isAnnotationPresent(Iri.class)) {
String uri = method.getAnnotation(Iri.class).value();
if (!namedMethods.containsKey(uri)
|| !isBridge(method, methods)) {
namedMethods.put(uri, method);
}
}
}
return namedMethods;
}
private int getRank(Method m) {
int rank = m.getAnnotations().length;
if (m.isAnnotationPresent(ParameterTypes.class))
return rank - 2;
return rank;
}
private boolean isSpecial(Method m) {
if (isObjectMethod(m))
return true;
if ("methodMissing".equals(m.getName()))
return true;
if ("propertyMissing".equals(m.getName()))
return true;
return m.isAnnotationPresent(InstancePrivate.class);
}
private Class>[] getParameterTypes(Method m) {
if (m.isAnnotationPresent(ParameterTypes.class))
return m.getAnnotation(ParameterTypes.class).value();
return m.getParameterTypes();
}
private boolean isBridge(Method method, Collection methods) {
for (Method m : methods) {
if (!m.getName().equals(method.getName()))
continue;
if (!Arrays.equals(getParameterTypes(m), getParameterTypes(method)))
continue;
if (!m.getReturnType().isAssignableFrom(method.getReturnType()))
return true;
}
return false;
}
private boolean implementMethod(Method method, String name, boolean bridge)
throws Exception {
List chain = chain(method);
List