001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.server.startup;
021    
022    import org.apache.commons.io.FileUtils;
023    import org.apache.commons.lang.StringUtils;
024    import org.slf4j.Logger;
025    import org.slf4j.LoggerFactory;
026    import org.sonar.api.config.Settings;
027    import org.sonar.api.utils.Logs;
028    import org.sonar.api.utils.SonarException;
029    import org.sonar.api.utils.TimeProfiler;
030    import org.sonar.api.utils.ZipUtils;
031    import org.sonar.api.web.GwtExtension;
032    import org.sonar.server.platform.ServerSettings;
033    
034    import java.io.File;
035    import java.io.IOException;
036    import java.net.URI;
037    import java.net.URISyntaxException;
038    import java.net.URL;
039    import java.util.zip.ZipEntry;
040    
041    public class GwtPublisher {
042      private static final Logger LOG = LoggerFactory.getLogger(GwtPublisher.class);
043    
044      private Settings settings;
045      private GwtExtension[] extensions = null;
046      private File outputDir = null;
047    
048      public GwtPublisher(GwtExtension[] extensions, Settings settings) {
049        this.extensions = extensions;
050        this.settings = settings;
051      }
052    
053      GwtPublisher(GwtExtension[] extensions, File outputDir) {
054        this.extensions = extensions;
055        this.outputDir = outputDir;
056      }
057    
058      GwtPublisher() {
059      }
060    
061      public void start() {
062        TimeProfiler profiler = new TimeProfiler().start("Deploy GWT plugins");
063        try {
064          cleanDirectory();
065          this.outputDir = new File(settings.getString(ServerSettings.DEPLOY_DIR), "gwt");
066          Logs.INFO.debug("publish {} GWT extensions to {}", extensions.length, outputDir);
067          publish();
068    
069        } catch (Exception e) {
070          throw new SonarException("can not publish GWT extensions", e);
071        }
072        profiler.stop();
073      }
074    
075      protected void cleanDirectory() {
076        try {
077          if (outputDir != null && outputDir.exists()) {
078            File[] files = outputDir.listFiles();
079            if (files != null) {
080              for (File file : files) {
081                // avoid issues with SCM hidden dirs
082                if (!file.isHidden()) {
083                  if (file.isDirectory()) {
084                    FileUtils.deleteDirectory(file);
085                    FileUtils.deleteDirectory(file);
086                  } else {
087                    file.delete();
088                  }
089                }
090              }
091            }
092          }
093    
094        } catch (IOException e) {
095          LOG.warn("can not clean the directory " + outputDir, e);
096        }
097      }
098    
099      protected void publish() throws IOException, URISyntaxException {
100        for (final GwtExtension module : extensions) {
101          URL sourceDir = module.getClass().getResource("/" + module.getGwtId() + "/");
102          if (sourceDir == null) {
103            throw new SonarException("Can not find the directory " + module.getGwtId() + " defined by the GWT module " + module.getClass().getName());
104          }
105          Logs.INFO.info("publish {} to {}", module.getGwtId(), outputDir);
106          if (sourceDir.toString().startsWith("jar:file")) {
107            // unzip the JAR
108            String path = StringUtils.substringBetween(sourceDir.toString(), "jar:file:", "!");
109            File gwtJar = new File(getCleanPath(path));
110            ZipUtils.unzip(gwtJar, outputDir, new ZipUtils.ZipEntryFilter() {
111              public boolean accept(ZipEntry entry) {
112                return entry.getName().startsWith(module.getGwtId());
113              }
114            });
115          } else {
116            // just copy the files
117            File source = new File(sourceDir.toURI());
118            FileUtils.copyDirectory(source, new File(outputDir, module.getGwtId()));
119          }
120        }
121      }
122    
123      protected String getCleanPath(String path) throws URISyntaxException {
124        return new URI(path).getPath();
125      }
126    }