/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.java.generation; import java.io.File; import java.util.Properties; import java.util.StringTokenizer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.IBuffer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ToolFactory; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.formatter.CodeFormatter; import org.eclipse.jdt.ui.CodeGeneration; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.text.edits.TextEdit; import org.jboss.tools.common.model.XModelObjectConstants; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.plugin.ModelPlugin; import org.jboss.tools.common.model.util.EclipseResourceUtil; public class JavaBeanGenerator { public static String PARAM_PACKAGENAME = "packageName"; //$NON-NLS-1$ public static String PARAM_SHORTNAME = "shortName"; //$NON-NLS-1$ public static String PARAM_ACCESS = "access"; //$NON-NLS-1$ public static String PARAM_EXTENDS = "extends"; //$NON-NLS-1$ public static String PARAM_IMPLEMENTS = "implements"; //$NON-NLS-1$ public static String PARAM_INTERFACE = "interface"; //$NON-NLS-1$ public static String ATT_CLASS_NAME = "class name"; //$NON-NLS-1$ public static String ATT_ACCESS_MODIFIER = "access modifier"; //$NON-NLS-1$ protected XModelObject context; protected Properties input; public void setContext(XModelObject context) { this.context = context; } public void setInput(Properties input) { this.input = input; } public IJavaProject getJavaProject() { IProject project = EclipseResourceUtil.getProject(context); return EclipseResourceUtil.getJavaProject(project); } public void generate() throws CoreException { IJavaProject javaproject = getJavaProject(); if(javaproject == null) return; String srcpath = getSrcLocation(javaproject); if(srcpath == null) return; String qclsname = input.getProperty(ATT_CLASS_NAME); String filepath = srcpath + XModelObjectConstants.SEPARATOR + qclsname.replace('.', '/') + ".java"; //$NON-NLS-1$ if(new File(filepath).exists()) return; int lastDot = qclsname.lastIndexOf('.'); Properties p = new Properties(); p.setProperty(PARAM_SHORTNAME, qclsname.substring(lastDot + 1)); p.setProperty(PARAM_PACKAGENAME, (lastDot < 0) ? "" : qclsname.substring(0, lastDot)); //$NON-NLS-1$ // String pkgname = (lastDot < 0) ? "" : qclsname.substring(0, lastDot); String access = input.getProperty(ATT_ACCESS_MODIFIER); if(access == null || "default".equals(access)) access = ""; //$NON-NLS-1$ //$NON-NLS-2$ p.setProperty(PARAM_ACCESS, access); p.setProperty(PARAM_EXTENDS, input.getProperty("extends")); //$NON-NLS-1$ p.setProperty(PARAM_IMPLEMENTS, input.getProperty("implements").replace(';', ',')); //$NON-NLS-1$ p.setProperty(PARAM_INTERFACE, input.getProperty("interface").replace(';', ',')); //$NON-NLS-1$ doGenerateJava(javaproject, filepath, p); } private String getSrcLocation(IJavaProject javaproject) throws CoreException { IClasspathEntry[] entries = javaproject.getResolvedClasspath(true); for (int i = 0; i < entries.length; i++) { if(entries[i].getEntryKind() != IClasspathEntry.CPE_SOURCE) continue; IResource resource = null; IPath projectPath = ModelPlugin.getWorkspace().getRoot().getFullPath(); if (projectPath!=null && projectPath.equals(projectPath.append(entries[i].getPath()))) { resource = ModelPlugin.getWorkspace().getRoot(); } else { resource = ModelPlugin.getWorkspace().getRoot().getFolder(entries[i].getPath()); } return resource.getLocation().toString(); } return null; } private void doGenerateJava(IJavaProject javaproject, String filepath, Properties p) throws CoreException { IPackageFragmentRoot root = getJavaProjectSrcRoot(javaproject); String pkgname = p.getProperty(PARAM_PACKAGENAME); IPackageFragment pack = root.getPackageFragment(pkgname); if(!pack.exists()) { pack= root.createPackageFragment(pkgname, true, null); } String shortname = p.getProperty(PARAM_SHORTNAME); String lineDelimiter = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ ICompilationUnit parentCU = pack.createCompilationUnit(shortname + ".java", "", false, null); //$NON-NLS-1$ //$NON-NLS-2$ ICompilationUnit createdWorkingCopy = (ICompilationUnit) parentCU.getWorkingCopy(null); /// imports= new ImportsStructure(createdWorkingCopy, prefOrder, threshold, false); /// imports.addImport(pack.getElementName(), getTypeName()); String typeContent = constructTypeStub(p, lineDelimiter); String cuContent= buildClassContent(parentCU, shortname, typeContent, lineDelimiter); createdWorkingCopy.getBuffer().setContents(cuContent); IType createdType = createdWorkingCopy.getType(shortname); /// imports.create(false, new SubProgressMonitor(monitor, 1)); ICompilationUnit cu = createdType.getCompilationUnit(); synchronized(cu) { cu.reconcile(ICompilationUnit.NO_AST, true, null, null); } /// imports.create(false, new SubProgressMonitor(monitor, 1)); /// synchronized(cu) { /// cu.reconcile(); /// } ISourceRange range = createdType.getSourceRange(); IBuffer buf = cu.getBuffer(); String originalContent= buf.getText(range.getOffset(), range.getLength()); String formattedContent = codeFormat2(CodeFormatter.K_CLASS_BODY_DECLARATIONS, originalContent, 0, lineDelimiter, cu.getJavaProject()); buf.replace(range.getOffset(), range.getLength(), formattedContent); cu.commitWorkingCopy(false, null); } private String buildClassContent(ICompilationUnit cls, String shortname, String typeContent, String lineDelimiter) throws CoreException { StringBuffer qName = new StringBuffer(); qName.append(shortname); String comments = CodeGeneration.getTypeComment(cls, qName.toString(), lineDelimiter); IPackageFragment p = (IPackageFragment)cls.getParent(); String content = CodeGeneration.getCompilationUnitContent(cls, comments, typeContent, lineDelimiter); if (content != null) { ASTParser parser = ASTParser.newParser(AST.JLS2); parser.setSource(content.toCharArray()); CompilationUnit unit = (CompilationUnit) parser.createAST(null); if ((p.isDefaultPackage() || unit.getPackage() != null) && !unit.types().isEmpty()) { return content; } } StringBuffer sb = new StringBuffer(); if(!p.isDefaultPackage()) { sb.append("package "); //$NON-NLS-1$ sb.append(p.getElementName()); sb.append(';'); } for (int i = 0; i < 2; i++) sb.append(lineDelimiter); if(comments != null) { sb.append(comments); sb.append(lineDelimiter); } sb.append(typeContent); return sb.toString(); } public static String codeFormat2(int kind, String sourceString, int indentationLevel, String lineSeparator, IJavaProject project) { TextEdit edit = ToolFactory.createCodeFormatter(project.getOptions(true)).format(kind, sourceString, 0, sourceString.length(), indentationLevel, lineSeparator); Document doc = new Document(sourceString); try { edit.apply(doc, 0); return doc.get(); } catch (BadLocationException e) { return sourceString; } } public static IPackageFragmentRoot getJavaProjectSrcRoot(IJavaProject javaProject) throws CoreException { IClasspathEntry[] es = javaProject.getResolvedClasspath(true); for (int i = 0; i < es.length; i++) { if(es[i].getEntryKind() != IClasspathEntry.CPE_SOURCE) continue; return javaProject.getPackageFragmentRoot(ModelPlugin.getWorkspace().getRoot().getFolder(es[i].getPath())); } return null; } private String constructTypeStub(Properties p, String lineDelimiter) { StringBuffer sb = new StringBuffer(); // String pkgname = p.getProperty(PARAM_PACKAGENAME); String access = p.getProperty(PARAM_ACCESS); if(access == null) access = ""; else if(access.length() > 0) access += " "; //$NON-NLS-1$ //$NON-NLS-2$ boolean isInterface = XModelObjectConstants.TRUE.equals(p.getProperty(PARAM_INTERFACE)); String kind = isInterface ? "interface " : "class "; //$NON-NLS-1$ //$NON-NLS-2$ String shortname = p.getProperty(PARAM_SHORTNAME); String _extends = p.getProperty(PARAM_EXTENDS); if(_extends == null) _extends = ""; else if(_extends.length() > 0) _extends = "extends " + _extends + " "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ String _implements = formatImplements(p.getProperty(PARAM_IMPLEMENTS)); if(_implements == null) { _implements = ""; //$NON-NLS-1$ } else if(_implements.length() > 0) { if(isInterface) { _implements = "extends " + _implements + " "; //$NON-NLS-1$ //$NON-NLS-2$ } else { _implements = "implements " + _implements + " "; //$NON-NLS-1$ //$NON-NLS-2$ } } String header = access + kind + shortname + " " + _extends + _implements + "{" + lineDelimiter; //$NON-NLS-1$ //$NON-NLS-2$ sb.append(header); if(!isInterface) { sb.append("public " + shortname + "() {" + lineDelimiter + "}" + lineDelimiter); // constructor //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } sb.append("}" + lineDelimiter); //$NON-NLS-1$ return sb.toString(); } private String formatImplements(String s) { StringBuffer sb = new StringBuffer(); StringTokenizer st = new StringTokenizer(s, ",;"); //$NON-NLS-1$ while(st.hasMoreTokens()) { sb.append(st.nextToken()); if(st.hasMoreTokens()) sb.append(", "); //$NON-NLS-1$ } return sb.toString(); } }