// $Id: TestJavaImportEnumeration.java 13911 2007-12-13 00:09:36Z euluis $ // Copyright (c) 2007 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.uml.reveng; import java.io.StringReader; import java.util.Collection; import java.util.Iterator; import junit.framework.TestCase; import org.argouml.model.InitializeModel; import org.argouml.model.Model; import org.argouml.profile.init.InitProfileSubsystem; import org.argouml.uml.reveng.java.JavaLexer; import org.argouml.uml.reveng.java.JavaRecognizer; import org.argouml.uml.reveng.java.Modeller; import antlr.RecognitionException; import antlr.TokenStreamException; /** * Test case to test the import of a Java source file containing a Java 5 enum. * <p> * The content of the Java source file is a private constant at the bottom of * the source of this class. The test methods are specially designed for this * Java source constant. Feeding of the diagram subsystem is disabled; only * model elements are created and checked. * <p> * @author Tom Morris */ public class TestJavaImportEnumeration extends TestCase { /* * @see junit.framework.TestCase#TestCase(String) */ public TestJavaImportEnumeration(String str) { super(str); InitializeModel.initializeDefault(); } /* * @see junit.framework.TestCase#setUp() */ protected void setUp() { if (isParsed) { return; } JavaLexer lexer = new JavaLexer(new StringReader(PARSERINPUT)); assertNotNull("Creation of lexer failed.", lexer); lexer.setTokenObjectClass("org.argouml.uml.reveng.java.ArgoToken"); JavaRecognizer parser = new JavaRecognizer(lexer); assertNotNull("Creation of parser failed.", parser); parsedModel = Model.getModelManagementFactory().createModel(); assertNotNull("Creation of model failed.", parsedModel); Model.getModelManagementFactory().setRootModel(parsedModel); new InitProfileSubsystem().init(); Modeller modeller = new Modeller(parsedModel, new DummyImportSettings(), "TestClass.java"); assertNotNull("Creation of Modeller instance failed.", modeller); try { parser.compilationUnit(modeller, lexer); isParsed = true; } catch (RecognitionException e) { fail("Parsing of Java source failed." + e); } catch (TokenStreamException e) { fail("Parsing of Java source failed." + e); } } /** * Test if the class with the enumeration stereotype was created */ public void testSimpleEnumeration() { if (parsedPackage == null) { parsedPackage = Model.getFacade().lookupIn(parsedModel, "testpackage"); assertNotNull("No package \"testpackage\" found in model.", parsedPackage); } parsedClass = Model.getFacade().lookupIn(parsedPackage, "TestClass"); Object mainClass = parsedClass; parsedClass = null; parsedClass = getEnumeration(mainClass, "Color"); // Attributes Collection attributes = Model.getFacade().getAttributes(parsedClass); assertNotNull("No attributes found in class.", attributes); assertEquals("Number of attributes is wrong", 3, attributes.size()); Object attribute = null; Object attributeGreen = null; Object attributeYellow = null; Object attributeRed = null; Iterator iter = attributes.iterator(); while (iter.hasNext()) { attribute = iter.next(); assertTrue("The attribute should be recognized as an attribute.", Model.getFacade().isAAttribute(attribute)); if ("GREEN".equals(Model.getFacade().getName(attribute))) { attributeGreen = attribute; } else if ("YELLOW".equals(Model.getFacade().getName(attribute))) { attributeYellow = attribute; } else if ("RED".equals(Model.getFacade().getName(attribute))) { attributeRed = attribute; } } assertTrue("The attributes have wrong names.", attributeGreen != null || attributeYellow != null || attributeRed != null); assertTrue("Attribute GREEN should be final.", Model.getFacade().isReadOnly(attributeGreen)); assertTrue("Attribute GREEN should be static.", Model.getFacade().isStatic(attributeGreen)); } /** * Look up an enumeration by name in its parent namespace * and check that it's properly formed. */ private Object getEnumeration(Object namespace, String name) { Object enumeration = Model.getFacade().lookupIn(namespace, name); assertNotNull("failed to find enumeration" + name, enumeration); assertEquals("Inconsistent class name.", name, Model.getFacade().getName(enumeration)); Collection stereotypes = Model.getFacade().getStereotypes(enumeration); assertNotNull("no stereotypes found", stereotypes); assertEquals("wrong number of stereotypes found", 1, stereotypes.size()); Object stereotype = stereotypes.iterator().next(); assertEquals("<<enumeration stereotype>> not found", "enumeration", Model.getFacade().getName(stereotype)); return enumeration; } /** * Test if the class with the enumeration stereotype was created */ public void testEnumeration() { if (parsedPackage == null) { parsedPackage = Model.getFacade().lookupIn(parsedModel, "testpackage"); assertNotNull("No package \"testpackage\" found in model.", parsedPackage); } parsedClass = Model.getFacade().lookupIn(parsedPackage, "TestClass"); assertNotNull("No class \"TestClass\" found.", parsedClass); assertEquals("Inconsistent class name.", "TestClass", Model.getFacade().getName(parsedClass)); assertEquals("The namespace of the class should be \"testpackage\".", parsedPackage, Model.getFacade().getNamespace(parsedClass)); Object mainClass = parsedClass; parsedClass = null; parsedClass = getEnumeration(mainClass, "MessagePriority"); // Attributes Collection attributes = Model.getFacade().getAttributes(parsedClass); assertNotNull("No attributes found in class.", attributes); assertEquals("Number of attributes is wrong", 4, attributes.size()); Object attribute = null; Object attributeVP = null; Object attributeLow = null; Object attributeNormal = null; Object attributeHigh = null; Iterator iter = attributes.iterator(); while (iter.hasNext()) { attribute = iter.next(); assertTrue("The attribute should be recognized as an attribute.", Model.getFacade().isAAttribute(attribute)); if ("valuePersist".equals(Model.getFacade().getName(attribute))) { attributeVP = attribute; } else if ("LOW".equals(Model.getFacade().getName(attribute))) { attributeLow = attribute; } else if ("NORMAL".equals(Model.getFacade().getName(attribute))) { attributeNormal = attribute; } else if ("HIGH".equals(Model.getFacade().getName(attribute))) { attributeHigh = attribute; } } assertTrue("The attributes have wrong names.", attributeVP != null || attributeLow != null || attributeNormal != null || attributeHigh != null); assertTrue("Attribute LOW should be final.", Model.getFacade().isReadOnly(attributeLow)); assertFalse("Attribute valuePersist should not be private.", Model.getFacade().isPrivate(attributeVP)); assertFalse("Attribute valuePersist should not be final.", Model.getFacade().isReadOnly(attributeVP)); Object attribType = Model.getFacade().getType(attributeVP); assertTrue("Attribute valuePersist should have type short.", "short".equals(Model.getFacade().getName(attribType))); // Operations Collection operations = Model.getFacade().getOperations(parsedClass); assertNotNull("No operations found in class.", operations); assertEquals("Number of operations is wrong", 3, operations.size()); Object operation = null; Object operationMP = null; Object operationCP = null; Object operationGVP = null; iter = operations.iterator(); while (iter.hasNext()) { operation = iter.next(); assertTrue("The operation should be recognized as an operation.", Model.getFacade().isAOperation(operation)); if ("MessagePriority".equals( Model.getFacade().getName(operation))) { operationMP = operation; } else if ("createPersist".equals(Model.getFacade().getName( operation))) { operationCP = operation; } else if ("getValuePersist".equals( Model.getFacade().getName(operation))) { operationGVP = operation; } } assertTrue("The operations have wrong names.", operationMP != null && operationCP != null && operationGVP != null); assertTrue("Constructor MessagePriority should be private.", Model.getFacade().isPrivate(operationMP)); assertEquals("The body of operation MessagePriority is wrong.", BODY2, getBody(operationMP)); assertTrue("Operation update should be public.", Model.getFacade().isPublic(operationCP)); assertEquals("The body of operation update is wrong.", BODY1, getBody(operationCP)); assertTrue("Operation createPersist should be static.", Model.getFacade().isStatic(operationCP)); assertTrue("Operation getString should be public.", Model.getFacade().isPublic(operationGVP)); assertEquals("The body of operation getString is wrong.", BODY3, getBody(operationGVP)); // TODO: check return types } /** * Gets the (first) body of an operation. * * @param operation The operation. * @return The first body. */ private static String getBody(Object operation) { String body = null; Collection methods = Model.getFacade().getMethods(operation); if (methods != null && !methods.isEmpty()) { Object expression = Model.getFacade().getBody(methods.iterator().next()); body = (String) Model.getFacade().getBody(expression); } return body; } /** * Flag, if the Java source is parsed already. */ private static boolean isParsed; /** * Instances of the model and it's components. */ private static Object parsedModel; private static Object parsedPackage; private static Object parsedClass; private static final String BODY1 = " switch (val) {\n" + " case 1:\n" + " return LOW;\n" + " case 5:\n" + " return NORMAL;\n" + " case 9:\n" + " return HIGH;\n" + " default:\n" + " throw new Exception (\"MessagePriority unknown\");\n" + " }\n"; private static final String BODY2 = " this.valuePersist = val;\n"; private static final String BODY3 = " return this.valuePersist;\n"; /** * Test input for the parser. It's the content of a Java source file. It's * hardcoded here, because this test case strongly depends on this. */ private static final String PARSERINPUT = "package testpackage;\n" + "public class TestClass {\n" + " public enum Color {GREEN, YELLOW, RED};" + " public enum MessagePriority {\n" + " LOW ((short) 1),\n" + " NORMAL ((short) 5),\n" + " HIGH ((short) 9);\n" + "\n" + " public static MessagePriority createPersist " + "(final short val) throws Exception {" + BODY1 + " }\n" + "\n" + " short valuePersist;\n" + "\n" + " private MessagePriority (final short val) {" + BODY2 + " }\n" + "\n" + " public int getValuePersist () {" + BODY3 + " }\n" + " }\n" + "}"; }