/** Called whenever the OSGi framework stops our bundle */
  public void stop(BundleContext bc) throws Exception {
    tracker.close();

    if ("org.h2.Driver".equals(bc.getProperty("headsup.db.driver"))) {
      try {
        ((HibernateStorage) Manager.getStorageInstance())
            .getHibernateSession()
            .createSQLQuery("SHUTDOWN")
            .executeUpdate();
      } catch (Exception e) {
        Manager.getLogger("StorageActivator").info("Unable to shut down DB - " + e.getMessage());
      }
    }
    HibernateUtil.shutdown();
  }
  public EmbeddedFilePanel(final String id, final File file, final Project project) {
    super(id);

    add(CSSPackageResource.getHeaderContribution(getClass(), "embeddedfile.css"));

    add(JavascriptPackageResource.getHeaderContribution(getClass(), "highlight/shCore.js"));
    add(JavascriptPackageResource.getHeaderContribution(getClass(), "highlight/shAutoloader.js"));
    add(JavascriptPackageResource.getHeaderContribution(getClass(), "highlight/bootstrap.js"));
    add(CSSPackageResource.getHeaderContribution(getClass(), "highlight/shCoreDefault.css"));

    final Mime mime = Mime.get(file.getName());

    if (mime.isEmbeddableImage()) {
      WebMarkupContainer image = new WebMarkupContainer("image-content");
      image.add(
          new Image(
              "image",
              new DynamicImageResource() {
                protected byte[] getImageData() {
                  try {
                    return toImageData(ImageIO.read(file));
                  } catch (IOException e) {
                    Manager.getLogger("BrowseFile").error("Unable to load data to image", e);
                    return null;
                  }
                }
              }));
      add(image);

      add(new WebMarkupContainer("text-content").setVisible(false));
      add(new WebMarkupContainer("binary-content").setVisible(false));
      add(new WebMarkupContainer("object-content").setVisible(false));
      return;
    }
    if (mime.isEmbeddableAudio() || mime.isEmbeddableVideo()) {
      WebMarkupContainer container = new WebMarkupContainer("object-content");
      final WebMarkupContainer object = new WebMarkupContainer("object");
      object.add(
          new AttributeModifier(
              "type",
              true,
              new Model<String>() {
                @Override
                public String getObject() {
                  // TODO add real mime types to the mime library
                  if (mime.isEmbeddableAudio()) {
                    return "audio/" + mime.getExtension();
                  } else {
                    return "video/" + mime.getExtension();
                  }
                }
              }));

      object.add(
          new AttributeModifier(
              "data",
              true,
              new Model<String>() {
                @Override
                public String getObject() {
                  String storagePath =
                      Manager.getStorageInstance().getDataDirectory().getAbsolutePath();

                  if (file.getAbsolutePath().length() > storagePath.length() + 1) {
                    String filePath = file.getAbsolutePath().substring(storagePath.length() + 1);
                    filePath = filePath.replace(File.separatorChar, ':');
                    try {
                      filePath = URLEncoder.encode(filePath, "UTF-8");
                      // funny little hack here, guess the decoding is not right
                      filePath = filePath.replaceAll("\\+", "%20");
                    } catch (UnsupportedEncodingException e) {
                      // ignore
                    }

                    String urlPath = object.urlFor(new ResourceReference("embed")).toString();
                    return urlPath.replace("/all/", "/" + project.getId() + "/")
                        + "/path/"
                        + filePath;
                  }

                  return ""; // not supported, someone is hacking the system...
                }
              }));

      container.add(object);
      add(container);

      add(new WebMarkupContainer("text-content").setVisible(false));
      add(new WebMarkupContainer("binary-content").setVisible(false));
      add(new WebMarkupContainer("image-content").setVisible(false));
      return;
    }

    // offer a download link for binary (or unknown) files
    if (mime.isBinary()) {
      WebMarkupContainer binary = new WebMarkupContainer("binary-content");
      binary.add(new DownloadLink("download", file));
      add(binary);

      add(new WebMarkupContainer("text-content").setVisible(false));
      add(new WebMarkupContainer("image-content").setVisible(false));
      add(new WebMarkupContainer("object-content").setVisible(false));

      return;
    }

    String content = "(unable to read file)";
    // for other types try to parse the content
    FileInputStream in = null;
    try {
      in = new FileInputStream(file);
      content = IOUtil.toString(in).replaceAll("<", "&lt;").replaceAll(">", "&gt;");
    } catch (IOException e) {
      Manager.getLogger("BrowseFile").error("Exception rendering file highlighting", e);
    } finally {
      IOUtil.close(in);
    }

    add(
        new Label("text-content", content)
            .setEscapeModelStrings(false)
            .add(
                new AttributeModifier(
                    "class",
                    true,
                    new Model<String>() {
                      @Override
                      public String getObject() {
                        if (mime.getSyntax() != null) {
                          return "code brush: " + mime.getSyntax();
                        }

                        return "code brush: text";
                      }
                    })));

    add(new WebMarkupContainer("binary-content").setVisible(false));
    add(new WebMarkupContainer("image-content").setVisible(false));
    add(new WebMarkupContainer("object-content").setVisible(false));
  }
/**
 * The main code for building a command line project.
 *
 * @author Andrew Williams
 * @since 1.0
 */
public class CommandLineBuildHandler {
  private static Logger log = Manager.getLogger(CommandLineBuildHandler.class.getName());

  protected static void runBuild(
      CommandLineProject project,
      PropertyTree config,
      File dir,
      File output,
      Build build,
      long buildId) {
    int result = -1;
    Writer buildOut = null;
    Process process = null;
    StreamGobbler serr = null, sout = null;
    try {
      buildOut = new FileWriter(output);

      String command = config.getProperty(CIApplication.CONFIGURATION_COMMAND_LINE.getKey());
      if (command == null) {
        command = (String) CIApplication.CONFIGURATION_COMMAND_LINE.getDefault();
      }

      // wrap it in a shell call so we can do things like "make && make install"
      String[] commands = new String[3];
      commands[0] = "sh";
      commands[1] = "-c";
      commands[2] = command;
      process = Runtime.getRuntime().exec(commands, null, dir);

      serr = new StreamGobbler(new InputStreamReader(process.getErrorStream()), buildOut);
      sout = new StreamGobbler(new InputStreamReader(process.getInputStream()), buildOut);
      serr.start();
      sout.start();

      result = process.waitFor();
    } catch (InterruptedException e) {
      // TODO use this hook when we cancel the process
    } catch (IOException e) {
      e.printStackTrace(new PrintWriter(buildOut));
      log.error("Unable to write to build output file - reported in build log", e);
    } finally {
      if (process != null) {
        // defensively try to close the gobblers
        if (serr != null && sout != null) {
          // check that our gobblers are finished...
          while (!serr.isComplete() || !sout.isComplete()) {
            log.debug("waiting 1s to close gobbler");
            try {
              Thread.sleep(1000);
            } catch (InterruptedException e) {
              // we were just trying to tidy up...
            }
          }
        }

        IOUtil.close(process.getOutputStream());
        IOUtil.close(process.getErrorStream());
        IOUtil.close(process.getInputStream());
        process.destroy();
      }

      IOUtil.close(buildOut);
    }

    build.setEndTime(new Date());
    if (result != 0) {
      build.setStatus(Build.BUILD_FAILED);
    } else {
      build.setStatus(Build.BUILD_SUCCEEDED);
    }
  }
}