ar.com.tadp.xml.rinzo.jdt.wizards.NewJAXBParserWizard.java Source code

Java tutorial

Introduction

Here is the source code for ar.com.tadp.xml.rinzo.jdt.wizards.NewJAXBParserWizard.java

Source

/*****************************************************************************
 * 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);
        }
    }

}