| /* |
| * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| */ |
| package promoter; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.PrintStream; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.StringTokenizer; |
| |
| import promoter.util.IO; |
| import promoter.util.XMLOutput; |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public class Repository |
| { |
| public static final boolean COMPRESS = false; |
| |
| private static final String PARENT_DIRECTORY = "../"; |
| |
| private RepositoryComposer composer; |
| |
| private File base; |
| |
| private String name; |
| |
| private String path; |
| |
| private int pathLevel; |
| |
| private List<String> children = new ArrayList<String>(); |
| |
| private String childRetention; |
| |
| private String targetInfo; |
| |
| private String targetVersions; |
| |
| private String apiBaselineURL; |
| |
| private String apiBaselineSize; |
| |
| private String webLabel; |
| |
| private int webPriority; |
| |
| private boolean webCollapsed; |
| |
| public Repository(RepositoryComposer composer, File base, String name, String path) |
| { |
| System.out.println(); |
| System.out.println("Generating repository " + name + ": " + new File(base, path).getAbsolutePath()); |
| |
| this.composer = composer; |
| this.base = base; |
| this.name = name; |
| this.path = path; |
| |
| StringTokenizer tokenizer = new StringTokenizer(path, "/"); |
| while (tokenizer.hasMoreTokens()) |
| { |
| tokenizer.nextToken(); |
| ++pathLevel; |
| } |
| } |
| |
| public final RepositoryComposer getComposer() |
| { |
| return composer; |
| } |
| |
| public final File getBase() |
| { |
| return base; |
| } |
| |
| public final String getName() |
| { |
| return name; |
| } |
| |
| public final String getPath() |
| { |
| return path; |
| } |
| |
| public final int getPathLevel() |
| { |
| return pathLevel; |
| } |
| |
| public final List<String> getChildren() |
| { |
| return Collections.unmodifiableList(children); |
| } |
| |
| public void addChild(String child) |
| { |
| try |
| { |
| File composite = new File(base, path); |
| File folder = new File(composite, child).getCanonicalFile(); |
| |
| System.out.println(" Adding child location: " + folder); |
| children.add(child); |
| } |
| catch (IOException ex) |
| { |
| throw new RuntimeException(ex); |
| } |
| } |
| |
| public String getChildRetention() |
| { |
| return childRetention; |
| } |
| |
| public String getTargetInfo() |
| { |
| return targetInfo; |
| } |
| |
| public String getTargetVersions() |
| { |
| return targetVersions; |
| } |
| |
| public String getApiBaselineURL() |
| { |
| return apiBaselineURL; |
| } |
| |
| public String getApiBaselineSize() |
| { |
| return apiBaselineSize; |
| } |
| |
| public String getWebLabel() |
| { |
| return webLabel; |
| } |
| |
| public int getWebPriority() |
| { |
| return webPriority; |
| } |
| |
| public boolean isWebCollapsed() |
| { |
| return webCollapsed; |
| } |
| |
| public String getAnchorName() |
| { |
| StringBuilder builder = new StringBuilder(); |
| for (char c : path.toCharArray()) |
| { |
| if (Character.isJavaIdentifierPart(c)) |
| { |
| builder.append(c); |
| } |
| else |
| { |
| builder.append('_'); |
| } |
| } |
| |
| return builder.toString(); |
| } |
| |
| public String getDownloadsURL(String... paths) |
| { |
| StringBuilder builder = new StringBuilder(path); |
| for (String p : paths) |
| { |
| builder.append("/"); |
| builder.append(p); |
| } |
| |
| return PromoterConfig.INSTANCE.formatUpdateURL(builder.toString()); |
| } |
| |
| public void generate(XMLOutput xml) |
| { |
| File folder = new File(base, path); |
| folder.mkdirs(); |
| |
| IO.writeFile(new File(folder, "composition.properties"), new IO.OutputHandler() |
| { |
| public void handleOutput(OutputStream out) throws IOException |
| { |
| PrintStream stream = new PrintStream(out); |
| stream.println("composite.name=" + name); |
| stream.flush(); |
| } |
| }); |
| |
| // IO.writeFile(new File(folder, "p2.index"), new IO.OutputHandler() |
| // { |
| // public void handleOutput(OutputStream out) throws IOException |
| // { |
| // PrintStream stream = new PrintStream(out); |
| // stream.println("version = 1"); |
| // stream.println("metadata.repository.factory.order = compositeContent.xml,\\!"); |
| // stream.println("artifact.repository.factory.order = compositeArtifacts.xml,\\!"); |
| // stream.flush(); |
| // } |
| // }); |
| |
| generateHTML(folder); |
| |
| generateXML(xml, folder, "compositeArtifacts", "compositeArtifactRepository", |
| "org.eclipse.equinox.internal.p2.artifact.repository.CompositeArtifactRepository"); |
| generateXML(xml, folder, "compositeContent", "compositeMetadataRepository", |
| "org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository"); |
| } |
| |
| protected void generateHTML(File folder) |
| { |
| File htmlFile = new File(folder, "index.html"); |
| PrintStream out = null; |
| |
| try |
| { |
| out = new PrintStream(htmlFile); |
| |
| String title = "CDO Composite Update Site (" + name + ")"; |
| |
| out.println("<!DOCTYPE html>"); |
| out.println("<html>"); |
| out.println("<head>"); |
| out.println(" <title>" + title + "</title>"); |
| out.println("</head>"); |
| out.println(); |
| out.println("<body style=\"font-family:Arial; font-size:small;\">"); |
| out.println("<h1>" + title + "</h1>"); |
| out.println("<p>"); |
| out.println("<em>For information about CDO or Net4j, see their <a href=\"https://www.eclipse.org/cdo\">homepage</a> or <a"); |
| out.println("href=\"http://wiki.eclipse.org/CDO\">wiki</a>."); |
| out.println(" <br> For information about installing or updating Eclipse software, see the"); |
| out.println(" <a href=\"http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.user/tasks/tasks-124.htm\">"); |
| out.println(" Eclipse Platform Help</a>."); |
| out.println(" <br> Some plugins require third party software from p2 repositories listed in this "); |
| out.println(" <a href=\"bookmarks.xml\">bookmarks.xml</a> file.</em>"); |
| out.println("</p>"); |
| |
| if (!children.isEmpty()) |
| { |
| out.println("<h3>Contents</h3>"); |
| out.println("<ul>"); |
| for (String child : children) |
| { |
| String label = child; |
| while (label.startsWith(PARENT_DIRECTORY)) |
| { |
| label = label.substring(PARENT_DIRECTORY.length()); |
| } |
| |
| out.println("<li><a href=\"" + child + "/index.html\">" + label + "</a></li>"); |
| } |
| |
| out.println("</ul>"); |
| } |
| else |
| { |
| out.println("<p><em>Currently this composite update site is empty.<br/>"); |
| out.println("This may change in the future when new builds are promoted.</em></p>"); |
| } |
| |
| out.println("</body>"); |
| out.println("</html>"); |
| } |
| catch (Exception ex) |
| { |
| throw new RuntimeException(ex); |
| } |
| finally |
| { |
| IO.close(out); |
| } |
| } |
| |
| protected void generateXML(final XMLOutput xml, final File folder, final String xmlName, final String entityName, final String typeName) |
| { |
| final File xmlFile = new File(folder, xmlName + ".xml"); |
| IO.writeFile(xmlFile, new IO.OutputHandler() |
| { |
| public void handleOutput(OutputStream out) throws IOException |
| { |
| try |
| { |
| XMLOutput repoXML = new XMLOutput(out); |
| repoXML.processingInstruction(entityName, "version=\"1.0.0\""); |
| |
| repoXML.element("repository"); |
| repoXML.attribute("name", name); |
| repoXML.attribute("type", typeName); |
| repoXML.attribute("version", "1.0.0"); |
| repoXML.push(); |
| |
| repoXML.element("properties"); |
| repoXML.attribute("size", "3"); |
| repoXML.push(); |
| |
| repoXML.element("property"); |
| repoXML.attribute("name", "p2.timestamp"); |
| repoXML.attribute("value", System.currentTimeMillis()); |
| |
| repoXML.element("property"); |
| repoXML.attribute("name", "p2.compressed"); |
| repoXML.attribute("value", COMPRESS); |
| |
| repoXML.element("property"); |
| repoXML.attribute("name", "p2.mirrorsURL"); |
| repoXML.attribute("value", PromoterConfig.INSTANCE.formatUpdateURL(path) + "&format=xml"); |
| repoXML.pop(); |
| |
| repoXML.element("children"); |
| repoXML.attribute("size", children.size()); |
| repoXML.push(); |
| |
| for (String child : children) |
| { |
| repoXML.element("child"); |
| repoXML.attribute("location", child); |
| } |
| |
| repoXML.pop(); |
| repoXML.pop(); |
| repoXML.done(); |
| |
| if (COMPRESS) |
| { |
| xml.element("zip"); |
| xml.attribute("destfile", new File(folder, xmlName + ".jar")); |
| xml.attribute("update", false); |
| xml.push(); |
| xml.element("fileset"); |
| xml.attribute("dir", folder); |
| xml.push(); |
| xml.element("include"); |
| xml.attribute("name", xmlFile.getName()); |
| xml.pop(); |
| xml.pop(); |
| } |
| } |
| catch (Exception ex) |
| { |
| throw new RuntimeException(ex); |
| } |
| } |
| }); |
| } |
| |
| void setProperties(Properties properties) |
| { |
| childRetention = properties.getProperty("child.retention"); |
| targetInfo = properties.getProperty("target.info"); |
| targetVersions = properties.getProperty("target.versions", ""); |
| apiBaselineURL = properties.getProperty("api.baseline.url"); |
| apiBaselineSize = properties.getProperty("api.baseline.size", ""); |
| webLabel = properties.getProperty("web.label", name); |
| webPriority = Integer.parseInt(properties.getProperty("web.priority", "500")); |
| webCollapsed = Boolean.parseBoolean(properties.getProperty("web.collapsed", "false")); |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| public static class Drops extends Repository |
| { |
| private String job; |
| |
| private String stream; |
| |
| private String types; |
| |
| private List<BuildInfo> buildInfos = new ArrayList<BuildInfo>(); |
| |
| public Drops(RepositoryComposer composer, File base, String name, String path, String job, String stream, String types, List<BuildInfo> buildInfos) |
| { |
| super(composer, base, name, path); |
| this.job = job; |
| this.stream = stream; |
| this.types = types; |
| |
| for (BuildInfo buildInfo : buildInfos) |
| { |
| if (job != null && !buildInfo.getJob().equals(job)) |
| { |
| continue; |
| } |
| |
| if (stream != null && !buildInfo.getStream().equals(stream)) |
| { |
| continue; |
| } |
| |
| if (types != null && !types.contains(buildInfo.getType())) |
| { |
| continue; |
| } |
| |
| File drop = new File(PromoterConfig.INSTANCE.getDropsArea(), buildInfo.getQualifier()); |
| if (new File(drop, DropProcessor.MARKER_INVISIBLE).isFile()) |
| { |
| continue; |
| } |
| |
| String child = PARENT_DIRECTORY; |
| for (int i = 0; i < getPathLevel(); i++) |
| { |
| child += PARENT_DIRECTORY; |
| } |
| |
| child += "drops/" + buildInfo.getQualifier(); |
| addChild(child); |
| addChild(child + "/categories"); |
| |
| this.buildInfos.add(buildInfo); |
| } |
| } |
| |
| public final String getJob() |
| { |
| return job; |
| } |
| |
| public final String getStream() |
| { |
| return stream; |
| } |
| |
| public final String getTypes() |
| { |
| return types; |
| } |
| |
| public final List<BuildInfo> getBuildInfos() |
| { |
| return buildInfos; |
| } |
| } |
| } |