/******************************************************************************* * Copyright (c) 2005-2012 eBay Inc. * 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 * *******************************************************************************/ package org.eclipse.vjet.eclipse.core.test.build.antsupport; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.StringTokenizer; import java.util.Vector; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; /** * Note: the steps are given at: * https://wiki2.arch.ebay.com/confluence/display/QE/Installation * * do below 3 things: Dsfbase depend on jsnativeresource correct bundle versions * if not correct correct src paths in build properties if not exist * * * */ public class BundleUpdateTask extends Task { private static final String BUNDLE_VERSION = "Bundle-Version:"; private static final String MANIFEST_MF_PATH = "META-INF/MANIFEST.MF"; private static final String REQUIRE_BUNDLE = "Require-Bundle:"; public static final String PROPERTY_SOURCE_PREFIX = "source.."; //$NON-NLS-1$ static String[] projects = new String[] { "DsfBase", "DsfPrebuild", "JsNativeResource", "uKernel", "uKernelCore" }; String projectDirectory; /** * set the location where to find the generated projects. * * @param dir */ public void setProjectDirectory(String dir) { this.projectDirectory = dir; } @Override public void execute() throws BuildException { if (projectDirectory == null) { throw new BuildException("Dir must be specified"); } for (String prj : projects) { File projectFile = new File(projectDirectory, prj); if (!projectFile.exists()) { throw new BuildException("cannot find project: " + prj + " under " + projectDirectory); } try { addDependency(projectFile); updateBundleVersions(projectFile); // updateBuildProperties(projectFile); } catch (Exception e) { throw new BuildException("unknown exception occurred ", e); } } super.execute(); } private void addDependency(File projFile) throws FileNotFoundException, IOException { // Modify bundle.DsfBase's MANIFEST.MF (not bundle.DsfPrebuild's) // 1. Double-click PackageExplorer->bundle.DsfBase\META-INF\MANIFEST.MF // (Note that you don't have to check it out.) // 2. Click on MANIFEST.MF tab on bottom. // 3. Add as non-last line in Require-Bundle: (don't forget the trailing // comma): // JsNativeResource;visibility:=reexport, // 4. Save if (projFile.getName().equals("DsfBase")) { File manifest = new File(projFile, MANIFEST_MF_PATH); if (!manifest.exists()) { throw new BuildException("cannot find Manifest.mf for project " + projFile.getName()); } List lines = readLines(new FileInputStream(manifest)); int startLine = 0; for (Object object : lines) { String line = (String) object; if (line.startsWith(REQUIRE_BUNDLE)) { break; } startLine++; } String line = (String) lines.get(startLine); if (line.startsWith(REQUIRE_BUNDLE)) { int endLine = startLine + 1; // go to next line while (endLine <= lines.size() - 1) { line = (String) lines.get(endLine); if (line.indexOf(": ") != -1) { // have a space is the gramar of Header endLine = endLine - 1; break;// has : means meet another header } endLine++; } line = (String) lines.get(endLine); if (!line.contains("JsNativeResource;visibility:=reexport")) { //yes! leave 2 spaces after \n lines.set(endLine, line + ",\n JsNativeResource;visibility:=reexport"); saveFile(manifest, lines); } } } } /** * //currently seems do not need this call if using BundleGenerator task. * but if we generate by ECLIPSE build plugin we need update * buildProperties. * * @param projFile * @throws FileNotFoundException * @throws IOException */ // private void updateBuildProperties(File projFile) // throws FileNotFoundException, IOException { // // File file = new File(projFile, "build.properties"); // // boolean searchBuild = file.exists(); // if (file.exists()) { // if (!file.canWrite()) // file.setWritable(true); // // ExternalBuildModel bModel = new ExternalBuildModel(projFile // .getAbsolutePath()) { // // @Override // public boolean isEditable() { // return true; // } // // }; // bModel.load(); // // IBuild build = bModel.getBuild(); // IBuildEntry entry = build.getEntry(PROPERTY_SOURCE_PREFIX); //$NON-NLS-1$ // // try { // if (entry != null) { // String[] tokens = entry.getTokens(); // for (String token : tokens) { // if (!new File(token).exists()) { // entry.removeToken(token); // } // } // if (entry.getTokens().length == 0) // build.remove(entry); // } // // PrintWriter printWriter=new PrintWriter(file.getAbsolutePath()); // build.write("", printWriter); // printWriter.flush(); // printWriter.close(); // // } catch (CoreException e) { // throw new BuildException(e); // } // } // // } private void updateBundleVersions(File projFile) throws FileNotFoundException, IOException { File manifest = new File(projFile, MANIFEST_MF_PATH); if (!manifest.exists()) { throw new BuildException("cannot find Manifest.mf for project " + projFile.getName()); } List lines = readLines(new FileInputStream(manifest)); int startLine = 0; for (Object object : lines) { String line = (String) object; if (line.startsWith(BUNDLE_VERSION)) { String version = line.substring(BUNDLE_VERSION.length()).trim(); String[] parts = version.split("\\."); if (parts.length > 4) { version = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[parts.length - 1]; lines.set(startLine, BUNDLE_VERSION + " " + version); saveFile(manifest, lines); } break; } startLine++; } } private void saveFile(File manifest, List lines) throws UnsupportedEncodingException, FileNotFoundException, IOException { StringBuffer sbuf = new StringBuffer(512); for (Object object2 : lines) { sbuf.append((String) object2).append("\n"); } // save lines writeFile(manifest.getAbsolutePath(), sbuf.toString(), "UTF-8"); } public static void writeFile(String fileName, String text, String characterEncoding) throws UnsupportedEncodingException, FileNotFoundException, IOException { FileOutputStream fos; byte[] buf = text.getBytes(characterEncoding); int numWritten; fos = new FileOutputStream(fileName); numWritten = 0; fos.write(buf, numWritten, buf.length); fos.close(); } /** * This is a convenience method thread reads an input stream into a List<String> * * @param inputStream * @return * @throws IOException */ public static List readLines(final InputStream inputStream) throws IOException { final String text = readStream(inputStream); StringTokenizer tokenizer = new StringTokenizer(text, "\n\r"); Vector list = new Vector(100); while (tokenizer.hasMoreElements()) { final String line = tokenizer.nextToken(); list.add(line); } return list; } /** * This is a convienence method to read text from an input stream into a * string. It will use the default encoding of the OS. It call the * underlying readString(InputStreamReader) * * @param inputStream - * InputStream * @return String - the text that was read in * @throws IOException */ public static String readStream(final InputStream inputStream) throws IOException { final InputStreamReader isr = new InputStreamReader(inputStream); try { return readStream(isr); } finally { isr.close(); } } /** * This is a convienence method to read text from a stream into a string. * The transfer buffer is 4k and the initial string buffer is 75k. If this * causes a problem, write your own routine. * * @param isr - * InputStreamReader * @return String - the text that was read in * @throws IOException */ public static String readStream(final InputStreamReader isr) throws IOException { StringBuffer sb = new StringBuffer(75000); char[] buf = new char[4096]; int numRead; do { numRead = isr.read(buf, 0, buf.length); if (numRead > 0) { sb.append(buf, 0, numRead); } } while (numRead >= 0); final String result = sb.toString(); return result; } public static void main(String[] args) { BundleUpdateTask update = new BundleUpdateTask(); update.setProjectDirectory("C:/Eric/workspaces3/ReleaseVjet"); update.execute(); } }