blob: f86ac1e7631a1fb820c7df1eef6a05bf9995584b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.nbbuild;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Delete;
import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.ZipFileSet;
import org.apache.tools.ant.types.selectors.SelectorUtils;
/**
* This task was created to create L10N kits. The xml to call this task might
* look like:
* <l10nTask nbmsdir="nbms" tmpdir="tmp" patternsFile="l10n.patterns"
* kitFile="build/l10n.zip"/>
*
*
* Resulting kitFile will contain the files according the patterns from
* patternsFile
*
* @author Michal Zlamal
*/
public class L10nTask extends Task {
File nbmsDir = null;
File tmpDir = null;
File patternsFile = null;
File kitFile = null;
String locales = "";
private static String LOCALES_TOKEN = "${locales}";
@Override
public void execute() throws BuildException {
LineNumberReader lnr = null;
try {
if (nbmsDir == null) {
throw new BuildException("Required variable not set. Set 'nbmsdir' in the calling build script file");
}
if (!nbmsDir.exists() || !nbmsDir.isDirectory()) {
throw new BuildException("'nbmsdir' has to exist and be directory where are all NBMs stored");
}
if (patternsFile == null) {
throw new BuildException("Required variable not set. Set 'patternsFile' in the calling build script file");
}
if (!patternsFile.exists() || !patternsFile.isFile()) {
throw new BuildException("'patternsFile' has to exist and be file with patterns what should be included in the kit");
}
if (kitFile == null) {
throw new BuildException("Required variable not set. Set 'kitFile' in the calling build script file");
}
lnr = new LineNumberReader(new FileReader(patternsFile));
String line;
Map<String, Set<String>> includes = new HashMap<>();
Map<String, Set<String>> excludes = new HashMap<>();
Set<String> excludeFiles = new HashSet<>();
//Read all the patterns from patternsFile
while ((line = lnr.readLine()) != null) {
if (line.trim().length() == 0) {
continue;
}
if (line.startsWith("#")) {
continue;
}
if (!line.startsWith("exclude ")) { //Include pattern
String[] p = line.split(":");
if (p.length != 2) {
if (line.endsWith(":")) {
includes.put(line.substring(0, line.length() - 1), null);
continue;
} else {
throw new BuildException("Wrong pattern '" + line + "' found in pattern file: " + patternsFile.getAbsolutePath());
}
}
Set<String> files = includes.get(p[0]);
if (files == null) {
files = new HashSet<>();
includes.put(p[0], files);
}
files.add(p[1]);
} else { //Exlude pattern
List<String> lines = new ArrayList<> ();
String lineRaw = line.substring("exclude ".length());
if (lineRaw.contains(LOCALES_TOKEN)) {
for (String locale : getLocales(locales)) {
if (! locale.isEmpty()) {
lines.add(lineRaw.replace(LOCALES_TOKEN, locale));
}
}
if (lines.isEmpty()) {
lines.add(lineRaw.replace(LOCALES_TOKEN, "*")); // NOI18N
}
} else {
lines.add(lineRaw); // NOI18N
}
for (String oneLine : lines) {
String[] p = oneLine.split(":");
if (p.length != 2) {
if (oneLine.endsWith(":")) {
excludes.put(oneLine.substring(0, oneLine.length() - 1), null);
excludeFiles.add(oneLine.substring(0, oneLine.length() - 1));
continue;
} else {
throw new BuildException("Wrong pattern '" + oneLine + "' found in pattern file: " + patternsFile.getAbsolutePath());
}
}
Set<String> files = excludes.get(p[0]);
if (files == null) {
files = new HashSet<>();
excludes.put(p[0], files);
}
files.add(p[1]);
}
}
}
lnr.close();
//Unzip all the NBMs
DirectoryScanner ds = new DirectoryScanner();
ds.setBasedir(nbmsDir);
ds.setIncludes(new String[]{"**/*.nbm"});
ds.scan();
String[] nbms = ds.getIncludedFiles();
Expand unzip = (Expand) getProject().createTask("unzip");
for (String nbm : nbms) {
File nbmFile = new File(nbmsDir, nbm);
File nbmDir = new File(tmpDir, nbm);
nbmDir.mkdirs();
unzip.setSrc(nbmFile);
unzip.setDest(nbmDir);
unzip.execute();
DirectoryScanner packGzDs = new DirectoryScanner();
final String suffix = ".jar.pack.gz";
packGzDs.setBasedir(nbmDir);
packGzDs.setIncludes(new String[]{"**/*" + suffix});
packGzDs.scan();
for (String packedJar : packGzDs.getIncludedFiles()) {
File packedJarFile = new File(nbmDir, packedJar);
File unpackedJarFile = new File(nbmDir, packedJar.substring(0, packedJar.length() - suffix.length()) + ".jar");
log("Unpacking " + packedJar + " to " + unpackedJarFile, Project.MSG_VERBOSE);
AutoUpdate.unpack200(packedJarFile, unpackedJarFile);
packedJarFile.delete();
}
}
ds.setBasedir(tmpDir);
String[] includesKeys = includes.keySet().toArray(new String[]{""});
String[] excludesKeys = excludes.keySet().toArray(new String[]{""});
if (includesKeys[0] != null) {
ds.setIncludes(includesKeys);
}
if (excludeFiles.size() > 0) {
ds.setExcludes(excludeFiles.toArray(new String[]{""}));
}
//Go though all the found files maching the first part of the pattern
ds.scan();
if (kitFile.exists()) {
kitFile.delete();
}
Zip zip = (Zip) getProject().createTask("zip");
zip.setDestFile(kitFile);
for (String filePath : ds.getIncludedFiles()) {
String file = filePath.replace("\\", "/");
ZipFileSet zipFileSet = new ZipFileSet();
boolean matching = false;
for (String include : includesKeys) {
if (SelectorUtils.matchPath(include, file)) {
Set<String> incPattern = includes.get(include);
if (incPattern != null) {
matching = true;
zipFileSet.appendIncludes(incPattern.toArray(new String[]{""}));
} else {
FileSet fileSet = new FileSet();
fileSet.setDir(tmpDir);
fileSet.setIncludes(file);
zip.addFileset(fileSet);
}
}
}
if (matching) {
for (String exclude : excludesKeys) {
if (SelectorUtils.matchPath(exclude, file)) {
Set<String> excPattern = excludes.get(exclude);
if (excPattern != null) {
zipFileSet.appendExcludes(excPattern.toArray(new String[]{""}));
}
}
}
File oneFile = new File(tmpDir, file);
zipFileSet.setSrc(oneFile);
file = file.replaceAll("org-netbeans-modules-", "");
file = file.replaceAll("/netbeans/modules/", "/");
file = file.replaceAll("\\.nbm/", "/");
file = file.replaceAll("\\.jar", "");
zipFileSet.setPrefix(file);
zip.addZipfileset(zipFileSet);
}
}
zip.execute();
Delete delete = (Delete) getProject().createTask("delete");
delete.setDir(tmpDir);
delete.execute();
} catch (FileNotFoundException ex) {
Logger.getLogger(L10nTask.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(L10nTask.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (lnr != null) {
lnr.close();
}
} catch (IOException ex) {
Logger.getLogger(L10nTask.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void setNbmsdir(File nbmsDir) {
this.nbmsDir = nbmsDir;
}
public void setTmpdir(File tmpDir) {
this.tmpDir = tmpDir;
}
public void setPatternsFile(File patternsFile) {
this.patternsFile = patternsFile;
}
public void setKitFile(File kitFile) {
this.kitFile = kitFile;
}
public void setLocales(String locales) {
this.locales = locales;
}
private static String[] getLocales(String locales) {
StringTokenizer en = new StringTokenizer(locales, ","); // NOI18N
String[] res = new String[en.countTokens()];
int i = 0;
while (en.hasMoreTokens()) {
res[i++] = en.nextToken();
}
return res;
}
}