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 */
020package org.sonar.server.startup;
021
022import org.apache.commons.io.FileUtils;
023import org.apache.commons.lang.StringUtils;
024import org.slf4j.Logger;
025import org.slf4j.LoggerFactory;
026import org.sonar.api.config.Settings;
027import org.sonar.api.utils.Logs;
028import org.sonar.api.utils.SonarException;
029import org.sonar.api.utils.TimeProfiler;
030import org.sonar.api.utils.ZipUtils;
031import org.sonar.api.web.GwtExtension;
032import org.sonar.server.platform.ServerSettings;
033
034import java.io.File;
035import java.io.IOException;
036import java.net.URI;
037import java.net.URISyntaxException;
038import java.net.URL;
039import java.util.zip.ZipEntry;
040
041public 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      LoggerFactory.getLogger(GwtPublisher.class).debug("Deploy {} GWT extensions to {}", extensions.length, outputDir);
067      publish();
068
069    } catch (Exception e) {
070      throw new IllegalStateException("Fail to deploy 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("Deploy {} 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}