001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.maven.plugin.xfire;
018    
019    import java.io.File;
020    import java.io.IOException;
021    import java.io.OutputStream;
022    import java.io.PrintStream;
023    import java.util.Iterator;
024    import java.util.List;
025    
026    import org.apache.maven.plugin.AbstractMojo;
027    import org.apache.maven.plugin.MojoExecutionException;
028    import org.apache.maven.project.MavenProject;
029    import org.apache.tools.ant.BuildEvent;
030    import org.apache.tools.ant.BuildException;
031    import org.apache.tools.ant.BuildListener;
032    import org.apache.tools.ant.Project;
033    import org.codehaus.xfire.gen.WsGenTask;
034    
035    /**
036     * WsGen mojo. <p/> Implemented as a wrapper around the XFire WsGen Ant task.
037     * 
038     * @author <a href="jerome@coffeebreaks.org">Jerome Lacoste</a>
039     * @version $Id$
040     * @goal wsgen
041     * @phase generate-sources
042     * @requiresProject
043     * @requiresDependencyResolution
044     */
045    public class WsgenMojo extends AbstractMojo {
046    
047        /**
048         * Project.
049         * 
050         * @parameter expression="${project}"
051         * @required
052         * @readonly
053         */
054        private MavenProject project;
055    
056        /**
057         * URLs
058         * 
059         * @parameter
060         * @required
061         */
062        private List wsdls;
063    
064        /**
065         * @parameter expression="${package}" alias="package"
066         */
067        private String thePackage; // reserved keyword...
068    
069        /**
070         * @parameter expression="${profile}"
071         */
072        private String profile;
073    
074        /**
075         * @parameter expression="${binding}"
076         */
077        private String binding;
078    
079        /**
080         * Will be added to the compileSourceRoot
081         * 
082         * @parameter expression="${outputDirectory}"
083         *            default-value="${project.build.directory}/generated-sources/xfire/wsgen"
084         * @required
085         */
086        private File outputDirectory;
087    
088        private PrintStream systemErr;
089    
090        //private PrintStream systemOut;
091    
092        private final PrintStream mySystemErr = new PrintStream(new MyErrorStream());
093    
094        //private final PrintStream mySystemOut = new PrintStream(new MyOutputStream());
095    
096        public void execute() throws MojoExecutionException {
097    
098            systemErr = System.err;
099            //systemOut = System.out;
100            System.setErr(mySystemErr);
101            // System.setOut(mySystemOut); // causes java.lang.OutOfMemoryError:
102            // Java heap space on my box
103    
104            try {
105                exec();
106            } finally {
107                System.setErr(systemErr);
108                // System.setOut( systemOut );
109            }
110        }
111    
112        class MyErrorStream extends OutputStream {
113            private StringBuffer buffer = new StringBuffer();
114    
115            public void write(final int b) throws IOException {
116                final char c = (char) b;
117                // shouldn't we handle '\r' as well ??
118                if (c == '\n') {
119                    getLog().error(buffer);
120                    buffer = new StringBuffer();
121                } else {
122                    buffer.append(c);
123                }
124            }
125        }
126    
127        class MyOutputStream extends OutputStream {
128            private StringBuffer buffer = new StringBuffer();
129    
130            public void write(final int b) throws IOException {
131                final char c = (char) b;
132                // shouldn't we handle '\r' as well ??
133                if (c == '\n') {
134                    getLog().info(buffer);
135                    buffer = new StringBuffer();
136                } else {
137                    buffer.append(c);
138                }
139            }
140        }
141    
142        private void exec() throws MojoExecutionException {
143    
144            if (wsdls.size() == 0) {
145                return;
146            }
147    
148            if (!outputDirectory.exists() && !outputDirectory.mkdirs()) {
149                getLog()
150                        .warn(
151                                "the output directory "
152                                        + outputDirectory
153                                        + " doesn't exist and couldn't be created. The goal with probably fail.");
154            }
155    
156            final Project antProject = new Project();
157    
158            antProject.addBuildListener(new DebugAntBuildListener());
159    
160            final WsGenTask task = new WsGenTask();
161    
162            task.setProject(antProject);
163    
164            if (binding != null) {
165                task.setBinding(binding);
166            }
167    
168            if (profile != null) {
169                task.setProfile(profile);
170            }
171    
172            if (thePackage != null) {
173                task.setPackage(thePackage);
174            }
175    
176            task.setOutputDirectory(outputDirectory.getAbsolutePath());
177    
178            for (Iterator iterator = wsdls.iterator(); iterator.hasNext();) {
179                String wsdlUrl = (String) iterator.next();
180    
181                if (!wsdlUrl.contains("://")) {
182                    wsdlUrl = new File(wsdlUrl).toURI().toString();
183                }
184    
185                task.setWsdl(wsdlUrl);
186    
187                getLog().info("Executing XFire WsGen task with url: " + wsdlUrl);
188    
189                try {
190                    task.execute();
191                } catch (BuildException e) {
192                    throw new MojoExecutionException("command execution failed", e);
193                }
194            }
195    
196            getLog().debug(
197                    "Adding outputDirectory to source root: " + outputDirectory);
198    
199            this.project.addCompileSourceRoot(outputDirectory.getAbsolutePath());
200        }
201    
202        private class DebugAntBuildListener implements BuildListener {
203            public void buildStarted(final BuildEvent buildEvent) {
204                getLog().debug(buildEvent.getMessage());
205            }
206    
207            public void buildFinished(final BuildEvent buildEvent) {
208                getLog().debug(buildEvent.getMessage());
209            }
210    
211            public void targetStarted(final BuildEvent buildEvent) {
212                getLog().debug(buildEvent.getMessage());
213            }
214    
215            public void targetFinished(final BuildEvent buildEvent) {
216                getLog().debug(buildEvent.getMessage());
217            }
218    
219            public void taskStarted(final BuildEvent buildEvent) {
220                getLog().debug(buildEvent.getMessage());
221            }
222    
223            public void taskFinished(final BuildEvent buildEvent) {
224                getLog().debug(buildEvent.getMessage());
225            }
226    
227            public void messageLogged(final BuildEvent buildEvent) {
228                getLog().debug(buildEvent.getMessage());
229            }
230        }
231    }