package strutsrewriting.handlers; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.Charset; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.Annotation; import org.eclipse.jdt.core.dom.ArrayInitializer; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.ImportDeclaration; import org.eclipse.jdt.core.dom.MemberValuePair; import org.eclipse.jdt.core.dom.NormalAnnotation; import org.eclipse.jdt.core.dom.SingleMemberAnnotation; import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.TypeDeclaration; import refactoring.struts.ActionMappingCreator; import refactoring.struts.ModuleAnnotations; import refactoring.struts.beans.FormBean; import refactoring.struts.beans.MappingAnnotationBean; import strutsrewriting.AnnotationVisitor; import strutsrewriting.RefactoringUtilities; import strutsrewriting.node.creator.CreateAnnotations; import tiles.refactor.TilesUtils; import tiles.refactor.beans.TilesDefinitionBean; /** * Our sample handler extends AbstractHandler, an IHandler base class. * @see org.eclipse.core.commands.IHandler * @see org.eclipse.core.commands.AbstractHandler */ public class SampleHandler extends AbstractHandler { /** * The constructor. */ public SampleHandler() { } /** * the command has been executed, so extract extract the needed information * from the application context. */ public Object execute(ExecutionEvent event) throws ExecutionException { try { receiveDataFromParser(); } catch (IOException e) { e.printStackTrace(); System.exit(0); } catch (ClassNotFoundException e) { e.printStackTrace(); System.exit(0); } return null; } public void receiveDataFromParser() throws IOException, ClassNotFoundException { ServerSocket mServerSocket = null; List moduleConfigs = null; List tilesBeans = null; try { mServerSocket = new ServerSocket(10001); Socket newConnectionSocket = mServerSocket.accept(); ObjectInputStream in = new ObjectInputStream(newConnectionSocket.getInputStream()); String msgType = (String) in.readObject(); if (msgType.equals("struts")) { moduleConfigs = (List) in.readObject(); } else if (msgType.equals("tiles")) { tilesBeans = (List) in.readObject(); } } finally { mServerSocket.close(); } if (moduleConfigs != null) { handleStruts(moduleConfigs); } else if (tilesBeans != null) { handleTiles(tilesBeans); } } private void handleStruts(List moduleAnnotations) { System.out.println("Received the STRUTS data"); for (ModuleAnnotations ma : moduleAnnotations) { System.out.println("Module: " + ma.getModulePrefix()); processModule(ma); System.out.println("---------------"); // break; // break; } } private void handleTiles(List tilesBeans) { System.out.println("Received the TILES data"); List annotatedDAs = null; try { annotatedDAs = TilesUtils.fetchAnnotatedClasses(); } catch (Exception e) { e.printStackTrace(); System.exit(0); } for (String fileNameDA : annotatedDAs) { String compilationUnitName = TilesUtils.fetchCompilationUnitName(fileNameDA); CompilationUnit unitDA = getFenixConcreteUnit(compilationUnitName); TypeDeclaration declaration = findTypeDeclarationDA(unitDA, compilationUnitName); String moduleName = fetchModuleFromMapping(declaration, compilationUnitName); if (isEmpty(moduleName)) { System.out.println("MM: " + compilationUnitName); continue; } for (Object obj : declaration.modifiers()) { if (!(obj instanceof Annotation)) { continue; } Annotation annotation = (Annotation) obj; String typeName = annotation.getTypeName().getFullyQualifiedName(); if (typeName.contains("Forwards")) { ArrayInitializer forwardsArray = null; NormalAnnotation singleAnnotation = null; if (annotation instanceof SingleMemberAnnotation) { SingleMemberAnnotation singleMemberAnn = (SingleMemberAnnotation) annotation; Expression expr = singleMemberAnn.getValue(); if (expr instanceof ArrayInitializer) { forwardsArray = (ArrayInitializer) expr; } else { singleAnnotation = (NormalAnnotation) expr; } } else { NormalAnnotation normalAnn = (NormalAnnotation) annotation; for (Object objNode : normalAnn.values()) { MemberValuePair pair = (MemberValuePair) objNode; if (pair.getName().getIdentifier().equals("value")) { forwardsArray = (ArrayInitializer) pair.getValue(); break; } } } if (singleAnnotation != null) { processForwardAnnotation(fileNameDA, tilesBeans, moduleName, singleAnnotation, unitDA.getAST()); } else { for (Object arrObj : forwardsArray.expressions()) { NormalAnnotation forwardAnn = (NormalAnnotation) arrObj; processForwardAnnotation(fileNameDA, tilesBeans, moduleName, forwardAnn, unitDA.getAST()); } } } } List imports = CreateAnnotations.createImportsForAnnotations(unitDA.getAST()); unitDA.imports().addAll(imports); System.out.println("Modified the AST: " + unitDA.toString() + "\n\n"); RefactoringUtilities.saveDirectlyModifiedUnit(unitDA); } System.out.println("Finished " + changesCtr); } private static long changesCtr = 0; private void processForwardAnnotation(String fileNameDA, List tilesBeansList, String moduleName, NormalAnnotation forwardAnn, AST ast) { for (Object obj : forwardAnn.values()) { MemberValuePair pair = (MemberValuePair) obj; if (pair.getName().getIdentifier().equals("path")) { String path = ((StringLiteral) pair.getValue()).getLiteralValue(); if (path.contains(".jsp")) { return; } List tilesFiles = fetchTilesFilesOfModule(tilesBeansList, moduleName); for (TilesDefinitionBean tilesBean : tilesBeansList) { if (!tilesFiles.contains(tilesBean.getFileName())) { continue; } String newPath = tilesBean.getProperties().get("body"); if (newPath != null && tilesBean.getDefinition().equals(path)) { System.out.println(fileNameDA + " forward to " + path + " is tile def that extends default " + " in module " + moduleName + " changed to " + newPath); ((StringLiteral) pair.getValue()).setLiteralValue(newPath); CreateAnnotations.changeForwardPathTiles(forwardAnn, ast, tilesBean.getProperties()); changesCtr++; return; } } } } } private static final Map modulesSpecial; static { modulesSpecial = new HashMap(); modulesSpecial.put("person/functionalities", "functionalities"); modulesSpecial.put("manager/functionalities", "functionalities"); modulesSpecial.put("projectsManagement", "institucionalProjectsManagement"); modulesSpecial.put("itProjectsManagement", "institucionalProjectsManagement"); } private List fetchTilesFilesOfModule(List tilesBeansList, String module) { if (modulesSpecial.keySet().contains(module)) { module = modulesSpecial.get(module); } for (TilesDefinitionBean tilesBean : tilesBeansList) { return tilesBean.getModuleToTiles().get(module); } return null; } private boolean isEmpty(String str) { if (str == null) { return true; } return str.isEmpty(); } private String fetchModuleFromMapping(TypeDeclaration declaration, String compilationUnitName) { String moduleName = null; for (Object obj : declaration.modifiers()) { if (!(obj instanceof NormalAnnotation)) { continue; } NormalAnnotation annotation = (NormalAnnotation) obj; String typeName = annotation.getTypeName().getFullyQualifiedName(); if (typeName.contains("Mapping")) { for (Object objNode : annotation.values()) { MemberValuePair pair = (MemberValuePair) objNode; if (pair.getName().getIdentifier().equals("module")) { try { moduleName = ((StringLiteral) pair.getValue()).getLiteralValue(); } catch (ClassCastException e) { if (compilationUnitName .equals("net.sourceforge.fenixedu.presentationTier.Action.administrativeOffice.lists.DiplomasListBySituationDA")) { return "academicAdminOffice"; } else if (compilationUnitName .equals("net.sourceforge.fenixedu.presentationTier.Action.administrativeOffice.lists.RequestListByDegreeDA")) { return "academicAdminOffice"; } } } } if (isEmpty(moduleName)) { return "default"; } } } return moduleName; } private void processModule(ModuleAnnotations ma) { //Map formNameAssociations = createFormBeanIfNeeded(ma); for (MappingAnnotationBean mapping : ma.getMappingAnnotations()) { // String formBeanName = mapping.getFormBean(); // if (formBeanName != null && !formBeanName.isEmpty()) { // String beanClass = formNameAssociations.get(formBeanName); // mapping.setFormBeanClass(beanClass); // } CompilationUnit unit = getFenixConcreteUnit(mapping.getDispatchActionClassName()); TypeDeclaration declaration = findTypeDeclarationDA(unit, mapping.getDispatchActionClassName()); List annotations = CreateAnnotations.createAnnotationsForDA(unit.getAST(), mapping); Collections.reverse(annotations); for (NormalAnnotation newAnnotation : annotations) { declaration.modifiers().add(0, newAnnotation); } List imports = CreateAnnotations.createImportsForAnnotations(unit.getAST()); unit.imports().addAll(imports); System.out.println("Modified the AST: " + unit.toString() + "\n\n"); RefactoringUtilities.saveDirectlyModifiedUnit(unit); // System.out.println("Saved the file!"); // break; } for (MappingAnnotationBean mapping : ma.getInterModuleConflictMappings()) { // String formBeanName = mapping.getFormBean(); // if (formBeanName != null && !formBeanName.isEmpty()) { // String beanClass = formNameAssociations.get(formBeanName); // mapping.setFormBeanClass(beanClass); // } CompilationUnit unit = getFenixConcreteUnit(mapping.getNewDAName()); TypeDeclaration declaration = findTypeDeclarationDA(unit, mapping.getNewDAName()); mapping.setDispatchActionClassName(mapping.getNewDAName()); List annotations = CreateAnnotations.createAnnotationsForDA(unit.getAST(), mapping); Collections.reverse(annotations); for (NormalAnnotation newAnnotation : annotations) { declaration.modifiers().add(0, newAnnotation); } List imports = CreateAnnotations.createImportsForAnnotations(unit.getAST()); unit.imports().addAll(imports); System.out.println("Modified the JIT created AST: " + unit.toString() + "\n\n"); RefactoringUtilities.saveDirectlyModifiedUnit(unit); } } /* * Create formBeans If they do not exist already */ private Map createFormBeanIfNeeded(ModuleAnnotations ma) { Map nameAssociations = new HashMap(); String baseFolder = ActionMappingCreator.FENIX_SRC_BASE_FOLDER; for (FormBean formBean : ma.getCreatedFormBeans()) { String classQualifiedName = formBean.getQualifiedName(); String classFile = new String(baseFolder + classQualifiedName.replace('.', '/') + ".java"); nameAssociations.put(formBean.getFormBean(), formBean.getQualifiedName()); FileInputStream fis; InputStreamReader isr = null; StringBuilder dispatchActionSourceCode = new StringBuilder(); boolean alreadyExists = false; try { fis = new FileInputStream(new File(classFile)); isr = new InputStreamReader(fis, Charset.forName("ISO-8859-1")); while (isr.ready()) { dispatchActionSourceCode.append((char) isr.read()); } alreadyExists = true; } catch (FileNotFoundException e) { alreadyExists = false; } catch (IOException e) { e.printStackTrace(); System.exit(0); } finally { if (isr != null) { try { isr.close(); } catch (IOException e) { e.printStackTrace(); System.exit(0); } } } if (alreadyExists) { continue; } FileOutputStream fos; OutputStreamWriter osw = null; try { File newFile = new File(classFile); newFile.getParentFile().mkdirs(); fos = new FileOutputStream(newFile); osw = new OutputStreamWriter(fos, Charset.forName("ISO-8859-1")); osw.write(formBean.getSourceCode()); } catch (FileNotFoundException e) { e.printStackTrace(); System.exit(0); } catch (IOException e) { e.printStackTrace(); System.exit(0); } finally { try { if (osw != null) { osw.flush(); osw.close(); } } catch (IOException e) { e.printStackTrace(); System.exit(0); } } } return nameAssociations; } private TypeDeclaration findTypeDeclarationDA(CompilationUnit unit, String qualifiedClassName) { String shortName = qualifiedClassName.substring(qualifiedClassName.lastIndexOf('.') + 1); TypeDeclaration typeDeclaration = null; for (Iterator iter = unit.types().iterator(); iter.hasNext();) { TypeDeclaration declaration = (TypeDeclaration) iter.next(); if (declaration.getName().getIdentifier().equals(shortName)) { typeDeclaration = declaration; break; } } return typeDeclaration; } private void applyAnnotations() { CompilationUnit unit = getFenixConcreteUnit("net.sourceforge.fenixedu.presentationTier.Action.student.administrativeOfficeServices.GeneratedDocumentsDA"); AnnotationVisitor visitor = new AnnotationVisitor(); unit.accept(visitor); } /** * Retrieves the ICompilationUnit of the 'fenix-mod-struts' project assumed * to exist in the runtime-application workspace of the launched eclipse to * test the plugin. Assumes to receive the className as Java would refer to * it: some.package.name.SomeClassName * * @param className * @return */ public ICompilationUnit getFenixIUnit(String className) { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IProject project = root.getProject("fenix-mod-struts"); ICompilationUnit file = null; try { project.open(null /* IProgressMonitor */); IJavaProject javaProject = JavaCore.create(project); IType lwType = javaProject.findType(className); file = lwType.getCompilationUnit(); } catch (CoreException e) { System.out.println("CoreException while geting unit: " + className); e.printStackTrace(); System.exit(0); } return file; } /** * Parses the AST corresponding to a CompilationUnit of a given className. * Assumes to receive the className as Java would refer to it: * some.package.name.SomeClassName * * @param className * @return */ public CompilationUnit getFenixConcreteUnit(String className) { ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setSource(getFenixIUnit(className)); parser.setKind(ASTParser.K_COMPILATION_UNIT); parser.setResolveBindings(true); CompilationUnit result = (CompilationUnit) parser.createAST(null); result.recordModifications(); return result; } }