/***************************************************************************** * This file is part of Rinzo * * Author: Claudio Cancinos * WWW: https://sourceforge.net/projects/editorxml * Copyright (C): 2008, Claudio Cancinos * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * 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 General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; If not, see <http://www.gnu.org/licenses/> ****************************************************************************/ package ar.com.tadp.xml.rinzo.jdt.wizards; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IConsoleManager; import org.eclipse.ui.console.MessageConsole; import org.eclipse.ui.console.MessageConsoleStream; import org.xml.sax.SAXParseException; import ar.com.tadp.xml.rinzo.XMLEditorPlugin; import ar.com.tadp.xml.rinzo.jdt.RinzoJDTPlugin; import ar.com.tadp.xml.rinzo.jdt.Utils; import com.sun.tools.xjc.Driver; import com.sun.tools.xjc.XJCListener; /** * Wizard to generate JAXB java classes binded to a schema definition plus a * JAXB parser to read and write from xml to objects and objects to xml * * @author ccancinos */ public class NewJAXBParserWizard extends Wizard implements INewWizard { private IStructuredSelection selection; private NewJAXBParserWizardPage newParserPage; private Collection<String> schemaLocations; private BindingFilesWizardPage bindingPage; private String template; public NewJAXBParserWizard(Collection<String> schemaLocations) { this.schemaLocations = schemaLocations; } public void init(IWorkbench workbench, IStructuredSelection selection) { this.selection = selection; } @Override public void addPages() { this.newParserPage = new NewJAXBParserWizardPage(this.selection); this.bindingPage = new BindingFilesWizardPage("Create JAXB Parser", "Select JAXB binding files"); addPage(this.newParserPage); addPage(this.bindingPage); } @Override public boolean performFinish() { try { Driver.run(this.createArgumentsList(), new XJCListenerExtension()); this.refreshSourceFolder(); this.createParser(); } catch (Exception e) { MessageDialog.openError(this.getShell(), "Generate JAXB Parser", e.getLocalizedMessage()); XMLEditorPlugin.log(e); return false; } return true; } private void refreshSourceFolder() throws CoreException { IWorkspaceRoot fWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); Path path = new Path(this.newParserPage.getPackageFragmentRootText()); fWorkspaceRoot.getFolder(path).refreshLocal(IResource.DEPTH_INFINITE, null); } private String[] createArgumentsList() { String sourceDirectory = this.newParserPage.getSourceDirectoryAbsolutePath(); String packageName = this.newParserPage.getPackage(); String encoding = this.newParserPage.getEncoding(); String targetVersion = this.newParserPage.getTargetVersion(); List<String> args = new ArrayList<String>(); for (String fileLocation : this.schemaLocations) { args.add(fileLocation); } args.add("-no-header"); args.add("-d"); args.add(sourceDirectory); args.add("-p"); args.add(packageName); args.add("-encoding"); args.add(encoding); args.add("-target"); args.add(targetVersion); args.add("-enableIntrospection"); if (this.newParserPage.isFluentAPI()) { args.add("-Xfluent-api"); } if (this.newParserPage.isValueConstructor()) { args.add("-Xvalue-constructor"); } if (this.newParserPage.isDefaultValue()) { args.add("-Xdefault-value"); } for (String bindingFile : this.bindingPage.getFiles()) { if (!Utils.isEmpty(bindingFile)) { args.add("-b"); args.add(bindingFile); } } String[] arguments = args.toArray(new String[] {}); return arguments; } private void createParser() throws JavaModelException { RootTypeFactoryMethod rootType = this.getRootType(); String className = rootType.getRootType() + "Parser.java"; IPackageFragment packageFragment = this.newParserPage.getPackageFragmentRoot().getPackageFragment( this.newParserPage.getPackage()); String source = this.getParserSourceCode(packageFragment.getElementName(), rootType.getMethodName(), rootType.getRootType()); packageFragment.createCompilationUnit(className, source, false, null); } private String getParserSourceCode(String packageName, String factoryMethodName, String rootType) { if (this.template == null) { this.template = this.readTemplate(); } return this.template .replaceAll("__PACKAGE__", packageName) .replaceAll("__TYPE__", rootType) .replaceAll("__FACTORY_METHOD__", factoryMethodName); } private String readTemplate() { URL url; try { url = new URL("platform:/plugin/" + RinzoJDTPlugin.PLUGIN_ID + "/resources/jaxbParserTemplate.java"); InputStream inputStream = url.openConnection().getInputStream(); BufferedReader in = new BufferedReader(new InputStreamReader(inputStream)); String inputLine; StringBuffer buffer = new StringBuffer(); while ((inputLine = in.readLine()) != null) { buffer.append(inputLine); buffer.append("\n"); } in.close(); return buffer.toString(); } catch (IOException e) { XMLEditorPlugin.log(e); } return ""; } private RootTypeFactoryMethod getRootType() { try { IMethod[] methods = this.newParserPage.getPackageFragmentRoot() .getPackageFragment(this.newParserPage.getPackage()).getCompilationUnit("ObjectFactory.java") .getType("ObjectFactory").getMethods(); for (IMethod method : methods) { String returnType = method.getReturnType(); if (returnType.contains("JAXBElement")) { String rootType = returnType.substring(returnType.indexOf("<"), returnType.lastIndexOf(">")); rootType = rootType.substring(rootType.indexOf("Q") + 1, rootType.lastIndexOf(";")); return new RootTypeFactoryMethod(method.getElementName(), rootType); } } for (IMethod method : methods) { String returnType = method.getReturnType(); if (!returnType.contains(".") && method.getElementName().startsWith("create")) { String rootType = returnType.substring(returnType.indexOf("Q") + 1, returnType.lastIndexOf(";")); return new RootTypeFactoryMethod(method.getElementName(), rootType); } } } catch (JavaModelException e) { XMLEditorPlugin.log(e); } return null; } private final class RootTypeFactoryMethod { private String methodName; private String rootType; public RootTypeFactoryMethod(String methodName, String rootType) { this.methodName = methodName; this.rootType = rootType; } public String getMethodName() { return methodName; } public String getRootType() { return rootType; } } private final class XJCListenerExtension extends XJCListener { private MessageConsole console; private MessageConsoleStream stream; public XJCListenerExtension() { console = this.getConsole(); stream = console.newMessageStream(); } private MessageConsole getConsole() { IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager(); for (IConsole consol : manager.getConsoles()) { if (consol.getName().equals(RinzoJDTPlugin.PLUGIN_ID)) { MessageConsole msgConsole = (MessageConsole) consol; msgConsole.clearConsole(); return msgConsole; } } MessageConsole messageConsole = new MessageConsole(RinzoJDTPlugin.PLUGIN_ID, null); messageConsole.activate(); manager.addConsoles(new IConsole[] { messageConsole }); return messageConsole; } public void warning(SAXParseException arg0) { stream.println("warning: " + arg0); } public void info(SAXParseException arg0) { stream.println("info: " + arg0); } public void fatalError(SAXParseException arg0) { stream.println("fatal error: " + arg0); } public void error(SAXParseException arg0) { stream.println("error: " + arg0); } } }