/**
* OpenSpotLight - Open Source IT Governance Platform
*
* Copyright (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA
* or third-party contributors as indicated by the @author tags or express
* copyright attribution statements applied by the authors. All third-party
* contributions are distributed under license by CARAVELATECH CONSULTORIA E
* TECNOLOGIA EM INFORMATICA LTDA.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
***********************************************************************
* OpenSpotLight - Plataforma de Governança de TI de Código Aberto
*
* Direitos Autorais Reservados (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA
* EM INFORMATICA LTDA ou como contribuidores terceiros indicados pela etiqueta
* @author ou por expressa atribuição de direito autoral declarada e atribuída pelo autor.
* Todas as contribuições de terceiros estão distribuídas sob licença da
* CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA.
*
* Este programa é software livre; você pode redistribuí-lo e/ou modificá-lo sob os
* termos da Licença Pública Geral Menor do GNU conforme publicada pela Free Software
* Foundation.
*
* Este programa é distribuído na expectativa de que seja útil, porém, SEM NENHUMA
* GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU ADEQUAÇÃO A UMA
* FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral Menor do GNU para mais detalhes.
*
* Você deve ter recebido uma cópia da Licença Pública Geral Menor do GNU junto com este
* programa; se não, escreva para:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.openspotlight.graph.query;
import static org.openspotlight.common.util.ClassPathResource.getResourceFromClassPath;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.openspotlight.common.exception.SLException;
import org.openspotlight.common.util.Files;
import org.openspotlight.common.util.HashCodes;
import org.openspotlight.common.util.StringBuilderUtil;
import org.openspotlight.graph.Context;
import org.openspotlight.graph.Node;
import org.openspotlight.graph.manipulation.GraphReader;
import org.openspotlight.graph.manipulation.GraphWriter;
import org.openspotlight.graph.metadata.Metadata;
import org.openspotlight.graph.query.Query.SortMode;
import org.openspotlight.graph.test.domain.link.ClassImplementsInterface;
import org.openspotlight.graph.test.domain.link.JavaClassHierarchy;
import org.openspotlight.graph.test.domain.link.JavaInterfaceHierarchy;
import org.openspotlight.graph.test.domain.link.PackageContainsType;
import org.openspotlight.graph.test.domain.link.TypeContainsMethod;
import org.openspotlight.graph.test.domain.node.JavaClass;
import org.openspotlight.graph.test.domain.node.JavaInnerInterface;
import org.openspotlight.graph.test.domain.node.JavaInterface;
import org.openspotlight.graph.test.domain.node.JavaPackage;
import org.openspotlight.graph.test.domain.node.JavaType;
import org.openspotlight.graph.test.domain.node.JavaTypeMethod;
public abstract class AbstractGeneralQueryTest {
/**
* The Class NodeWrapper.
*
* @author Vitor Hugo Chagas
*/
public class NodeWrapper {
/**
* The name.
*/
private String name;
/**
* The node.
*/
private Node node;
/**
* The parent name.
*/
private String parentName;
/**
* The type name.
*/
private String typeName;
/**
* Instantiates a new node wrapper.
*
* @param node the node
*/
public NodeWrapper(final Node node) {
this.node = node;
}
/**
* Instantiates a new node wrapper.
*
* @param typeName the type name
* @param parentName the parent name
* @param name the name
*/
public NodeWrapper(final String typeName, final String parentName,
final String name) {
this.typeName = typeName;
this.parentName = parentName;
this.name = name;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equalsTo(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
return hashCode() == obj.hashCode();
}
/**
* Gets the name.
*
* @return the name
*/
public String getName() {
if (name == null) {
name = node.getName();
}
return name;
}
/**
* Gets the parent name.
*
* @return the parent name
*/
public String getParentName() {
if (parentName == null) {
parentName = session.getParentNode(node).getName();
}
return parentName;
}
/**
* Gets the type name.
*
* @return the type name
*/
public String getTypeName() {
if (typeName == null) {
typeName = node.getTypeName();
}
return typeName;
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return HashCodes.hashOf(getTypeName(), getParentName(), getName());
}
/**
* Sets the name.
*
* @param name the new name
*/
public void setName(final String name) {
this.name = name;
}
/**
* Sets the parent name.
*
* @param parentName the new parent name
*/
public void setParentName(final String parentName) {
this.parentName = parentName;
}
/**
* Sets the type name.
*
* @param typeName the new type name
*/
public void setTypeName(final String typeName) {
this.typeName = typeName;
}
}
private static Callable<Void> shutdownHandler;
private final boolean didItRun = false;
/**
* The LOGGER.
*/
protected final Logger LOGGER = Logger.getLogger(getClass());
/**
* The print info.
*/
protected boolean printInfo = false;
protected GraphReader session;
protected SortMode sortMode = SortMode.NOT_SORTED;
protected GraphWriter writer;
/**
* Load classes.
*
* @param fileName the file name
* @return the collection< class<?>>
* @throws SLException the SL exception
* @throws IOException Signals that an I/O exception has occurred.
* @throws ClassNotFoundException the class not found exception
*/
private static Collection<Class<?>> loadClasses(final String fileName)
throws SLException, IOException, ClassNotFoundException {
final Collection<Class<?>> classes = new ArrayList<Class<?>>();
final String packagePath = AbstractGeneralQueryTest.class.getPackage()
.getName().replace('.', '/');
final String filePath = packagePath + '/' + fileName;
final InputStream inputStream = getResourceFromClassPath(filePath);
final Collection<String> names = Files.readLines(inputStream);
inputStream.close();
for (final String name: names) {
final String className = "java.util.".concat(name).trim();
final Class<?> clazz = Class.forName(className);
classes.add(clazz);
}
return classes;
}
/**
* Random tag.
*
* @return the int
*/
private static int randomTag() {
return (int) Math.round(Math.random() * 100.0);
}
/**
* Finish.
*/
@AfterClass
public static void finish()
throws Exception {
shutdownHandler.call();
shutdownHandler = null;
}
/**
* Adds the class implements interface links.
*
* @param root the root
* @param clazz the clazz
* @param javaClass the java class
*/
private void addClassImplementsInterfaceLinks(final Context root,
final Class<?> clazz, final JavaClass javaClass) {
final Class<?>[] iFaces = clazz.getInterfaces();
for (final Class<?> iFace: iFaces) {
final Package iFacePack = iFace.getPackage();
final JavaPackage javaPackage = writer.addNode(root,
JavaPackage.class, iFacePack.getName());
// javaPackage.setCaption(iFacePack.getName());
final JavaInterface javaInterface = writer.addChildNode(
javaPackage, JavaInterface.class, iFace.getName());
// javaInterface.setCaption(iFace.getName());
final ClassImplementsInterface link = writer.addLink(
ClassImplementsInterface.class, javaClass, javaInterface);
link.setTag(randomTag());
}
}
/**
* Adds the java class contains java class method.
*
* @param clazz the clazz
* @param javaClass the java class
*/
private void addJavaClassContainsJavaClassMethod(final Class<?> clazz,
final JavaClass javaClass) {
final Method[] methods = clazz.getDeclaredMethods();
for (final Method method: methods) {
final JavaTypeMethod javaTypeMethod = writer.addChildNode(
javaClass, JavaTypeMethod.class, method.getName());
// javaTypeMethod.setCaption(method.getName());
final TypeContainsMethod link = writer.addLink(
TypeContainsMethod.class, javaClass, javaTypeMethod);
link.setTag(randomTag());
}
}
/**
* Adds the java class hirarchy links.
*
* @param root the root
* @param clazz the clazz
* @param javaClass the java class
*/
private void addJavaClassHirarchyLinks(final Context root,
final Class<?> clazz, final JavaClass javaClass) {
final Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
final Package classPack = clazz.getPackage();
final JavaPackage javaPackage = writer.addNode(root,
JavaPackage.class, classPack.getName());
// javaPackage.setCaption(classPack.getName());
final JavaClass superJavaClass = writer.addChildNode(javaPackage,
JavaClass.class, superClass.getName());
writer.addLink(PackageContainsType.class, javaPackage,
superJavaClass);
writer.addLink(JavaClassHierarchy.class, javaClass, superJavaClass);
addJavaClassHirarchyLinks(root, superClass, superJavaClass);
}
}
/**
* Adds the java interface contains java method.
*
* @param iFace the i face
* @param javaInterface the java interface
*/
private void addJavaInterfaceContainsJavaMethod(final Class<?> iFace,
final JavaInterface javaInterface) {
final Method[] methods = iFace.getDeclaredMethods();
for (final Method method: methods) {
final JavaTypeMethod javaTypeMethod = writer.addChildNode(
javaInterface, JavaTypeMethod.class, method.getName());
// javaTypeMethod.setCaption(method.getName());
final TypeContainsMethod link = writer.addLink(
TypeContainsMethod.class, javaInterface, javaTypeMethod);
link.setTag(randomTag());
}
}
/**
* Adds the java interface hirarchy links.
*
* @param root the root
* @param iFace the i face
* @param javaInterface the java interface
*/
private void addJavaInterfaceHirarchyLinks(final Context root,
final Class<?> iFace, final JavaInterface javaInterface) {
final Class<?>[] superIFaces = iFace.getInterfaces();
for (final Class<?> superIFace: superIFaces) {
final Package iFacePack = iFace.getPackage();
final JavaPackage javaPackage = writer.addNode(root,
JavaPackage.class, iFacePack.getName());
// javaPackage.setCaption(iFacePack.getName());
final JavaInterface superJavaInterface = writer.addChildNode(
javaPackage, JavaInterface.class, superIFace.getName());
writer.addLink(PackageContainsType.class, javaPackage,
superJavaInterface);
// superJavaInterface.setCaption(superIFace.getName());
writer.addLink(JavaInterfaceHierarchy.class, javaInterface,
superJavaInterface);
addJavaInterfaceHirarchyLinks(root, superIFace, superJavaInterface);
}
}
protected boolean appearsAfter(final NodeWrapper[] wrappers, final String firstType,
final String firstStr, final String afterType, final String afterStr) {
return appearsAfter(wrappers, firstType, "java.util", firstStr,
afterType, "java.util", afterStr);
}
protected boolean appearsAfter(final NodeWrapper[] wrappers, final String firstType,
final String firstParent, final String firstStr, final String afterType,
final String afterParent, final String afterStr) {
final NodeWrapper first = new NodeWrapper(firstType, firstParent, firstStr);
final NodeWrapper after = new NodeWrapper(afterType, afterParent, afterStr);
int firstIndex = -1, afterIndex = -1;
for (int i = 0, size = wrappers.length; i < size; i++) {
if (wrappers[i].equals(first)) {
firstIndex = i;
}
if (wrappers[i].equals(after)) {
afterIndex = i;
}
if (firstIndex != -1 && afterIndex != -1) {
break;
}
}
return afterIndex > firstIndex;
}
protected abstract Callable<Void> createShutdownHandler();
protected abstract Callable<Void> createStartUpHandler();
/**
* Gets the resource content.
*
* @param resourceName the resource name
* @return the resource content
*/
protected String getResourceContent(final String resourceName) {
try {
final InputStream in = this.getClass().getResourceAsStream(
resourceName);
final Reader reader = new InputStreamReader(in);
final StringBuilder text = new StringBuilder();
final char[] buf = new char[1024];
int len = 0;
while ((len = reader.read(buf)) >= 0) {
text.append(buf, 0, len);
}
return text.toString();
} catch (final Exception e) {
return "";
}
}
protected abstract GraphReader graphReader();
/**
* Prints the result.
*
* @param nodes the nodes
*/
protected void printResult(final Collection<Node> nodes) {
if (printInfo && !nodes.isEmpty()) {
final StringBuilder buffer = new StringBuilder();
StringBuilderUtil.append(buffer, "\n\nRESULTS (", nodes.size(),
"):\n");
for (final Node node: nodes) {
StringBuilderUtil.append(buffer, StringUtils.rightPad(
node.getTypeName(), 60), StringUtils.rightPad(
node.getName(), 60), session.getParentNode(node)
.getName(), '\n');
}
LOGGER.info(buffer);
}
}
/**
* Wrap nodes.
*
* @param nodes the nodes
* @return the node wrapper[]
*/
protected NodeWrapper[] wrapNodes(final List<Node> nodes) {
final NodeWrapper[] wrappers = new NodeWrapper[nodes.size()];
for (int i = 0; i < wrappers.length; i++) {
wrappers[i] = new NodeWrapper(nodes.get(i));
}
return wrappers;
}
/**
* Prints the asserts.
*
* @param wrappers the wrappers
*/
void printAsserts(final NodeWrapper[] wrappers) {
final StringBuilder buffer = new StringBuilder();
StringBuilderUtil
.append(buffer, '\n', "assertThat(wrappers.length, is(",
wrappers.length, "));", '\n');
for (final NodeWrapper wrapper: wrappers) {
String pattern =
"assertThat(new NodeWrapper(${typeName}.class.getName(), \"${parentName}\", \"${name}\"), isOneOf(wrappers));";
pattern = StringUtils.replace(pattern, "${typeName}",
wrapper.getTypeName());
pattern = StringUtils.replace(pattern, "${parentName}",
wrapper.getParentName());
pattern = StringUtils
.replace(pattern, "${name}", wrapper.getName());
buffer.append(pattern).append('\n');
}
buffer.append('\n');
LOGGER.info(buffer);
}
/**
* Prints the asserts in order.
*
* @param wrappers the wrappers
*/
void printAssertsInOrder(final NodeWrapper[] wrappers) {
final StringBuilder buffer = new StringBuilder();
StringBuilderUtil
.append(buffer, '\n', "assertThat(wrappers.length, is(",
wrappers.length, "));", '\n');
for (int i = 0; i < wrappers.length; i++) {
final NodeWrapper wrapper = wrappers[i];
String pattern =
"assertThat(new NodeWrapper(${typeName}.class.getName(), \"${parentName}\", \"${name}\"), is(wrappers[${index}]));";
pattern = StringUtils.replace(pattern, "${typeName}",
wrapper.getTypeName());
pattern = StringUtils.replace(pattern, "${parentName}",
wrapper.getParentName());
pattern = StringUtils
.replace(pattern, "${name}", wrapper.getName());
pattern = StringUtils.replace(pattern, "${index}", "" + i);
buffer.append(pattern).append('\n');
}
buffer.append('\n');
LOGGER.info(buffer);
}
/**
* Gets the resource content. Populate graph.
*/
@Before
public void populateGraph()
throws Exception {
if (!didItRun) {
createStartUpHandler().call();
shutdownHandler = createShutdownHandler();
session = graphReader();
sortMode = SortMode.SORTED;
final Metadata metadata = session.getMetadata();
if (metadata.getMetaNodeType(JavaType.class) != null) { return; }
final Collection<Class<?>> iFaces = loadClasses("java-util-interfaces.txt");
final Collection<Class<?>> classes = loadClasses("java-util-classes.txt");
final Context context = session.getContext("queryTest");
final Package pack = java.util.Date.class.getPackage();
final JavaPackage utilJavaPackage = writer.addNode(context,
JavaPackage.class, pack.getName());
// utilJavaPackage.setCaption(pack.getName());
int count = 0;
final float floatValue = 0.3F;
for (final Class<?> iFace: iFaces) {
final JavaInterface javaInterface = writer.addChildNode(
utilJavaPackage, JavaInterface.class, iFace.getName());
writer.addLink(PackageContainsType.class, utilJavaPackage,
javaInterface);
// javaInterface.setCaption(iFace.getName());
javaInterface.setIntValue(count);
javaInterface.setDecValue(new Float(count + floatValue));
javaInterface.setBoolValue(new Boolean(true));
addJavaInterfaceHirarchyLinks(context, iFace, javaInterface);
addJavaInterfaceContainsJavaMethod(iFace, javaInterface);
count++;
}
count = 0;
for (final Class<?> clazz: classes) {
// context = session.createContext("queryTest2");
final JavaClass javaClass = writer.addChildNode(
utilJavaPackage, JavaClass.class, clazz.getName());
writer.addLink(PackageContainsType.class, utilJavaPackage,
javaClass);
// javaClass.setCaption(clazz.getName());
javaClass.setIntValue(count);
javaClass.setDecValue(new Float(count + floatValue));
javaClass.setBoolValue(new Boolean(false));
addJavaClassHirarchyLinks(context, clazz, javaClass);
addClassImplementsInterfaceLinks(context, clazz, javaClass);
addJavaClassContainsJavaClassMethod(clazz, javaClass);
count++;
}
final JavaInnerInterface javaInnerInterface = writer.addChildNode(
utilJavaPackage, JavaInnerInterface.class,
java.util.Map.Entry.class.getName());
Assert.assertNotNull(javaInnerInterface);
writer.flush();
}
}
}