/*
* ModeShape (http://www.modeshape.org)
*
* Licensed 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.modeshape.sequencer.javafile;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.modeshape.sequencer.javafile.metadata.AbstractMetadata.PRIVATE;
import static org.modeshape.sequencer.javafile.metadata.AbstractMetadata.PUBLIC;
import static org.modeshape.sequencer.javafile.metadata.AbstractMetadata.STATIC;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.modeshape.sequencer.javafile.metadata.AnnotationMetadata;
import org.modeshape.sequencer.javafile.metadata.FieldMetadata;
import org.modeshape.sequencer.javafile.metadata.ImportMetadata;
import org.modeshape.sequencer.javafile.metadata.JavaMetadata;
import org.modeshape.sequencer.javafile.metadata.MethodMetadata;
import org.modeshape.sequencer.javafile.metadata.ModifierMetadata;
import org.modeshape.sequencer.javafile.metadata.PackageMetadata;
import org.modeshape.sequencer.javafile.metadata.TypeMetadata;
import org.modeshape.sequencer.javafile.metadata.Variable;
/**
* Unit test for {@link JavaMetadata}
*
* @author Serge Pagop
* @author Horia Chiorean
*/
public class JavaMetadataTest {
private InputStream stream;
private JavaMetadata javaMetadata;
private ASTNode rootNode = null;
@Before
public void beforeEach() throws Exception {
File source = new File(getClass().getClassLoader().getResource("org/acme/MySource.java").toURI());
stream = new FileInputStream(source);
javaMetadata = JavaMetadata.instance(stream, JavaMetadataUtil.length(stream), null);
rootNode = CompilationUnitParser.runJLS3Conversion(JavaMetadataUtil.getJavaSourceFromTheInputStream(new FileInputStream(
source),
source.length(),
null),
true);
}
@After
public void afterEach() throws Exception {
if (stream != null) {
try {
stream.close();
} finally {
stream = null;
}
}
}
@Test
public void shouldGetJavaSourceFromTheInputStream() throws Exception {
char[] c = JavaMetadataUtil.getJavaSourceFromTheInputStream(stream, JavaMetadataUtil.length(stream), null);
assertThat(c, is(notNullValue()));
}
@Test
public void shouldRunJLS3Conversion() throws Exception {
assertThat(rootNode, is(notNullValue()));
// Verify we get a compilation unit node and that binding are correct
assertTrue("Not a compilation unit", rootNode.getNodeType() == ASTNode.COMPILATION_UNIT);
}
@Test
public void shouldCreatePackageMetadata() throws Exception {
PackageMetadata packageMetadata = javaMetadata.createPackageMetadata((CompilationUnit)rootNode);
assertThat(packageMetadata, is(notNullValue()));
assertThat(packageMetadata.getName(), is("org.acme"));
List<AnnotationMetadata> annotations = packageMetadata.getAnnotations();
for (AnnotationMetadata annotationMetadata : annotations) {
assertEquals(AnnotationMetadata.Type.MARKER, annotationMetadata.getType());
assertThat(annotationMetadata.getName(), is("org.acme.annotation.MyPackageAnnotation"));
}
}
@Test
public void shouldCreateImportMetadata() throws Exception {
List<ImportMetadata> data = javaMetadata.createImportMetadata((CompilationUnit)rootNode);
assertEquals(2, data.size());
ImportMetadata singleImport = data.get(0);
assertEquals(ImportMetadata.Type.SINGLE, singleImport.getType());
assertEquals("org.acme.annotation.MyClassAnnotation", singleImport.getName());
ImportMetadata onDemandImport = data.get(1);
assertEquals(ImportMetadata.Type.ON_DEMAND, onDemandImport.getType());
assertEquals("java.util", onDemandImport.getName());
}
@Test
public void shouldCreateTopLevelTypeMetadata() throws Exception {
List<TypeMetadata> types = javaMetadata.createTypeMetadata((CompilationUnit)rootNode);
assertEquals(1, types.size());
TypeMetadata typeMetadata = types.get(0);
assertClassMetadata(typeMetadata);
assertClassAnnotations(typeMetadata);
assertClassFields(typeMetadata);
assertClassMethods(typeMetadata);
}
private void assertClassMethods( TypeMetadata typeMetadata ) {
// get methods (member functions)
List<MethodMetadata> methods = typeMetadata.getMethods();
assertEquals(10, methods.size());
assertMethodMetadata(methods.get(0), MethodMetadata.Type.CONSTRUCTOR, new String[0], null, "MySource", 0);
MethodMetadata methodMetadata = methods.get(1);
assertMethodMetadata(methodMetadata, MethodMetadata.Type.CONSTRUCTOR, new String[] {PUBLIC}, null, "MySource", 2);
List<FieldMetadata> parameters = methodMetadata.getParameters();
assertFieldMetadata(parameters.get(0), FieldMetadata.Type.PRIMITIVE, new String[0], "int", new String[] {"i"});
assertFieldMetadata(parameters.get(1), FieldMetadata.Type.PRIMITIVE, new String[0], "int", new String[] {"j"});
methodMetadata = methods.get(2);
assertMethodMetadata(methodMetadata, MethodMetadata.Type.CONSTRUCTOR, new String[] {PUBLIC}, null, "MySource", 3);
parameters = methodMetadata.getParameters();
assertFieldMetadata(parameters.get(0), FieldMetadata.Type.PRIMITIVE, new String[0], "int", new String[] {"i"});
assertFieldMetadata(parameters.get(1), FieldMetadata.Type.PRIMITIVE, new String[0], "int", new String[] {"j"});
assertFieldMetadata(parameters.get(2), FieldMetadata.Type.SIMPLE, new String[0], "Object", new String[] {"o"});
assertMethodMetadata(methods.get(3), MethodMetadata.Type.METHOD_TYPE_MEMBER, new String[] {PUBLIC}, "int", "getI", 0);
methodMetadata = methods.get(4);
assertMethodMetadata(methodMetadata, MethodMetadata.Type.METHOD_TYPE_MEMBER, new String[] {PUBLIC}, "void", "setI", 1);
parameters = methodMetadata.getParameters();
assertFieldMetadata(parameters.get(0), FieldMetadata.Type.PRIMITIVE, new String[0], "int", new String[] {"i"});
methodMetadata = methods.get(5);
assertMethodMetadata(methodMetadata, MethodMetadata.Type.METHOD_TYPE_MEMBER, new String[] {PUBLIC}, "void", "setJ", 1);
parameters = methodMetadata.getParameters();
assertFieldMetadata(parameters.get(0), FieldMetadata.Type.PRIMITIVE, new String[0], "int", new String[] {"j"});
methodMetadata = methods.get(6);
assertMethodMetadata(methodMetadata,
MethodMetadata.Type.METHOD_TYPE_MEMBER,
new String[] {PUBLIC},
"void",
"doSomething",
3);
parameters = methodMetadata.getParameters();
assertFieldMetadata(parameters.get(0), FieldMetadata.Type.PRIMITIVE, new String[0], "int", new String[] {"p1"});
assertFieldMetadata(parameters.get(1), FieldMetadata.Type.PRIMITIVE, new String[0], "double", new String[] {"p2"});
assertFieldMetadata(parameters.get(2), FieldMetadata.Type.SIMPLE, new String[0], "Object", new String[] {"o"});
methodMetadata = methods.get(7);
assertMethodMetadata(methodMetadata,
MethodMetadata.Type.METHOD_TYPE_MEMBER,
new String[] {PUBLIC},
"void",
"doSomething",
4);
parameters = methodMetadata.getParameters();
assertFieldMetadata(parameters.get(0), FieldMetadata.Type.PRIMITIVE, new String[0], "int", new String[] {"p1"});
assertFieldMetadata(parameters.get(1), FieldMetadata.Type.PRIMITIVE, new String[0], "double", new String[] {"p2"});
assertFieldMetadata(parameters.get(2), FieldMetadata.Type.PRIMITIVE, new String[0], "float", new String[] {"p3"});
assertFieldMetadata(parameters.get(3), FieldMetadata.Type.SIMPLE, new String[0], "Object", new String[] {"o"});
methodMetadata = methods.get(8);
assertMethodMetadata(methodMetadata,
MethodMetadata.Type.METHOD_TYPE_MEMBER,
new String[] {PRIVATE},
"double",
"doSomething2",
2);
parameters = methodMetadata.getParameters();
assertFieldMetadata(parameters.get(0), FieldMetadata.Type.ARRAY, new String[0], "Object", new String[] {"oa"});
assertFieldMetadata(parameters.get(1), FieldMetadata.Type.ARRAY, new String[0], "int", new String[] {"ia"});
methodMetadata = methods.get(9);
assertMethodMetadata(methodMetadata,
MethodMetadata.Type.METHOD_TYPE_MEMBER,
new String[] {PUBLIC},
"Object",
"doSomething3",
0);
}
private void assertClassFields( TypeMetadata typeMetadata ) {
// get fields (member types)
List<FieldMetadata> fields = typeMetadata.getFields();
assertEquals(8, fields.size());
assertFieldMetadata(fields.get(0), FieldMetadata.Type.PRIMITIVE, new String[] {PRIVATE}, "int", new String[] {"i", "j"});
assertFieldMetadata(fields.get(1),
FieldMetadata.Type.PRIMITIVE,
new String[] {PRIVATE, STATIC},
"double",
new String[] {"a"});
assertFieldMetadata(fields.get(2), FieldMetadata.Type.PARAMETRIZED, new String[] {PRIVATE}, "List", new String[] {"l"});
assertFieldMetadata(fields.get(3), FieldMetadata.Type.PARAMETRIZED, new String[] {PRIVATE}, "A", new String[] {"o"});
assertFieldMetadata(fields.get(4), FieldMetadata.Type.SIMPLE, new String[] {PRIVATE}, "X", new String[] {"x"});
assertFieldMetadata(fields.get(5), FieldMetadata.Type.ARRAY, new String[] {PRIVATE}, "int", new String[] {"ia"});
assertFieldMetadata(fields.get(6), FieldMetadata.Type.ARRAY, new String[] {PRIVATE}, "Object", new String[] {"oa"});
assertFieldMetadata(fields.get(7), FieldMetadata.Type.ARRAY, new String[] {PRIVATE}, "Collection", new String[] {"ca"});
}
private void assertClassAnnotations( TypeMetadata typeMetadata ) {
// annotations of the top level class
List<AnnotationMetadata> annotations = typeMetadata.getAnnotations();
assertEquals(1, annotations.size());
AnnotationMetadata annotationMetadata = annotations.get(0);
assertEquals(AnnotationMetadata.Type.MARKER, annotationMetadata.getType());
assertThat(annotationMetadata.getName(), is("MyClassAnnotation"));
}
private void assertClassMetadata( TypeMetadata typeMetadata ) {
assertEquals(TypeMetadata.Type.CLASS, typeMetadata.getType());
// meta types of a top level class
assertThat(typeMetadata.getName(), is("MySource"));
// modifiers of the top level class
assertNotNull(typeMetadata.getModifiers());
assertFalse(typeMetadata.getModifiers().isEmpty());
assertThat(typeMetadata.getModifiers().get(0).getName(), is(PUBLIC));
}
private void assertFieldMetadata( FieldMetadata fieldMetadata,
FieldMetadata.Type expectedMetaType,
String[] expectedModifiers,
String expectedTypeName,
String[] expectedVariables ) {
assertEquals(expectedMetaType, fieldMetadata.getMetadataType());
assertEquals(expectedTypeName, fieldMetadata.getType());
List<ModifierMetadata> modifiers = fieldMetadata.getModifiers();
assertEquals(expectedModifiers.length, modifiers.size());
for (int i = 0; i < expectedModifiers.length; i++) {
assertEquals(expectedModifiers[i], modifiers.get(i).getName());
}
List<Variable> variables = fieldMetadata.getVariables();
assertEquals(expectedVariables.length, variables.size());
for (int i = 0; i < expectedVariables.length; i++) {
assertEquals(expectedVariables[i], variables.get(i).getName());
}
}
private void assertMethodMetadata( MethodMetadata methodMetadata,
MethodMetadata.Type expectedMetaType,
String[] expectedModifiers,
String returnType,
String name,
int expectedParamCount ) {
assertEquals(expectedMetaType, methodMetadata.getType());
if (returnType != null) {
assertEquals(returnType, methodMetadata.getReturnType().getType());
} else {
assertNull(methodMetadata.getReturnType());
}
assertEquals(methodMetadata.getName(), name);
List<ModifierMetadata> modifiers = methodMetadata.getModifiers();
assertEquals(expectedModifiers.length, modifiers.size());
for (int i = 0; i < expectedModifiers.length; i++) {
assertEquals(expectedModifiers[i], modifiers.get(i).getName());
}
assertEquals(expectedParamCount, methodMetadata.getParameters().size());
}
}