blob: 970077f603f635a0023c98951cb206349f819180 [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.* ;
import java.util.* ;
import org.apache.tools.ant.* ;
import org.apache.tools.ant.taskdefs.* ;
import org.apache.tools.ant.types.* ;
/** Runs the makenbm task for each locale specified in the
* global property locmakenbm.locales.
* NOTE: Currently this runs makelnbm, since the new
* functionality in that hasn't been merged into makenbm
* yet.
*
* @author Jerry Huth (email: jerry@solidstep.com)
*/
public class LocMakeNBM extends Task {
protected String locales = null ;
protected String mainDir = null ;
protected File topDir = null ;
protected String fileName = null ;
protected String moduleName = null ;
protected String baseFileName = null ;
protected boolean deleteInfo = false ;
protected String nbmIncludes = null ;
protected String modInfo = null ;
protected String findLocBundle = "." ; // relative to the directory
// corresponding to the module's
// codename
protected File locBundle = null ; // path to localizing bundle - overrides
// findLocBundle
protected String locIncludes = null ; // comma-separated list of
// "<locale>:<pattern>" elements
public void setLocales( String s) {
locales = s ;
}
public void setMainDir( String s) {
mainDir = s ;
}
public void setTopDir( File f) {
topDir = f ;
}
public void setModule(String module) {
this.moduleName = module;
log("Setting moduleName = '"+moduleName+"'", Project.MSG_VERBOSE);
}
public void setFile( String s) {
fileName = s ;
log("Setting fileName = '"+fileName+"'", Project.MSG_VERBOSE);
if( !fileName.substring( fileName.length() - 4).equals( ".nbm")) { //NOI18N
throw new BuildException( "Incorrect NBM file name \""+ s+"\". NBM file name must end in '.nbm'") ;
}
baseFileName = fileName.substring( 0, fileName.length() - 4) ;
}
public void setDeleteInfo( boolean b) {
deleteInfo = b ;
}
public void setNbmIncludes( String s) {
nbmIncludes = s ;
}
public void setModInfo( String s) {
modInfo = s ;
}
public void setLocBundle( File f) {
locBundle = f ;
}
public void setFindLocBundle( String s) {
findLocBundle = s ;
}
public void setLocIncludes( String s) {
locIncludes = s ;
}
public void execute() throws BuildException {
try {
really_execute() ;
} catch( BuildException be) {
be.printStackTrace();
throw be ;
}
}
public void really_execute() throws BuildException {
String locs, loc ;
StringTokenizer stok ;
LinkedList<String> build_locales = new LinkedList<>() ;
// Set default values. //
if( mainDir == null) {
mainDir = new String( "netbeans") ; //NOI18N
}
if( topDir == null) {
topDir = getProject().getBaseDir() ;
}
if (( modInfo == null) && (moduleName != null)) {
// load module info frommodule jarfile
File f = new File (topDir,moduleName.replace('/', File.separatorChar));
java.util.jar.JarFile jf;
try {
jf= new java.util.jar.JarFile(f);
} catch (java.io.IOException ioe) {
throw new BuildException("I/O error during opening module jarfile", ioe, this.getLocation());
}
java.util.jar.Manifest mani;
try {
mani = jf.getManifest();
} catch (java.io.IOException ioe) {
throw new BuildException("I/O error getting manifest from file '"+f.getAbsolutePath()+"'", ioe, this.getLocation());
}
if ( mani != null ) {
java.util.jar.Attributes attr = mani.getMainAttributes();
String cname = JarWithModuleAttributes.extractCodeName(attr);
String sver = attr.getValue("OpenIDE-Module-Specification-Version");
if ((cname != null) && (!(cname.equals(""))) && (sver != null) && (!(sver.equals("")))) {
modInfo = cname + '/' + sver;
log("Gathered module information from module jarfile. Codename = '"+cname+"' and specification version = '"+sver+"'",Project.MSG_VERBOSE);
} else {
throw new BuildException("Module in file '"+f.getAbsolutePath()+"' does not have either OpenIDE-Module attribute or OpenIDE-Module-Specification-Version attributes or missing both.", this.getLocation());
}
}
}
// Print a warning and stop if the topDir doesn't exist. //
if( printMissingDirWarning()) {
return ;
}
locs = getLocales() ;
if( locs == null || locs.trim().equals( "")) { //NOI18N
throw new BuildException( "Must specify 1 or more locales.") ;
}
if( fileName == null) {
throw new BuildException( "Must specify the file attribute.") ;
}
// I couldn't get it to work unless I explicitly added the task def here. //
getProject().addTaskDefinition("makelnbm", MakeLNBM.class); //NOI18N
// Get a list of the locales for which localized files exist. //
stok = new StringTokenizer( locs, ",") ; //NOI18N
while( stok.hasMoreTokens()) {
loc = stok.nextToken() ;
log("Checking if module has files in locale '"+loc+"'", Project.MSG_VERBOSE);
if( hasFilesInLocale( loc)) {
build_locales.add( loc) ;
log("Module has files in locale '"+loc+"'", Project.MSG_VERBOSE);
} else {
log("Module has no files in locale '"+loc+"'", Project.MSG_VERBOSE);
}
}
// For each locale that we need to build an NBM for. //
ListIterator<String> iterator = build_locales.listIterator() ;
while( iterator.hasNext()) {
// Build the NBM for this locale. //
buildNbm( iterator.next()) ;
}
}
/** Build the NBM for this locale. */
protected void buildNbm( String locale) throws BuildException {
MakeLNBM makenbm ;
LinkedList<String> list = new LinkedList<>() ;
String includes = new String() ;
File licenseFile ;
boolean first_time ;
Delete del ;
// Delete the Info directory if desired. //
if( deleteInfo) {
del = (Delete) getProject().createTask("delete"); //NOI18N
del.init() ;
del.setDir( new File( topDir.getAbsolutePath() + File.separator + "Info")) ; //NOI18N
del.execute() ;
del.setDir( new File( topDir.getAbsolutePath() + File.separator + "Info_" + //NOI18N
locale)) ;
del.execute() ;
}
else {
// Move the Info_<locale> dir to Info. //
switchInfo( true, locale) ;
}
makenbm = (MakeLNBM) getProject().createTask("makelnbm"); //NOI18N
makenbm.init() ;
makenbm.setModInfo( modInfo) ;
makenbm.setLangCode( locale) ;
String fname = getLocalizedFileName( locale);
makenbm.setFile( new File( getProject().getBaseDir().getAbsolutePath() +
File.separator + fname)) ;
makenbm.setTopdir( topDir) ;
makenbm.setIsStandardInclude( false) ;
String distbase = getProject().getProperty("dist.base"); //NOI18N
if (distbase != null) {
// try {
int idx = fname.lastIndexOf('/');
makenbm.setDistribution(distbase + "/" + fname.substring(idx + 1)); //NOI18N
// } catch (MalformedURLException e) {
// throw new BuildException(e, getLocation());
// }
}
licenseFile = getLicenseFile( locale) ;
if( licenseFile != null) {
MakeLNBM.Blurb blurb = makenbm.createLicense() ;
blurb.setFile( licenseFile) ;
}
// Set the localizing bundle specified, or look for it. //
if( locBundle != null) {
setLocBundle( makenbm, getSpecificLocBundleFile( locBundle, locale)) ;
}
else {
setLocBundle( makenbm, findLocBundle( makenbm, locale)) ;
}
// Set up the signing data if it's specified. //
if( getKeystore() != null &&
getStorepass() != null &&
getAlias() != null) {
MakeLNBM.Signature sign = makenbm.createSignature() ;
sign.setKeystore( new File( getKeystore())) ;
sign.setStorepass( getStorepass()) ;
sign.setAlias( getAlias()) ;
}
// Get the list of include patterns for this locale. //
addLocalePatterns( list, locale) ;
// Create a comma-separated list of include patterns. //
first_time = true ;
for (String s1: list) {
if( !first_time) {
includes += "," ; //NOI18N
}
includes += s1 ;
first_time = false ;
}
// Add any extra includes that were specified. //
if( nbmIncludes != null && !nbmIncludes.trim().equals( "")) { //NOI18N
if( !first_time) {
includes += "," ; //NOI18N
}
includes += nbmIncludes ;
}
makenbm.setIncludes( includes) ;
makenbm.execute() ;
// Move the Info dir to Info_<locale>. //
switchInfo( false, locale) ;
}
/** Return the license file associated with this locale if there is
* one.
*/
protected File getLicenseFile( String locale) {
String license_prop_name = locale + ".license.file" ; //NOI18N
String license_prop = getProject().getProperty(license_prop_name);
File license = null ;
if( license_prop != null) {
license = new File( license_prop ) ;
}
return( license) ;
}
protected void switchInfo( boolean to_info,
String locale) {
File dir ;
if( to_info) {
dir = new File( topDir.getAbsolutePath() + File.separator + "Info_" + locale) ; //NOI18N
dir.renameTo( new File( topDir.getAbsolutePath() + File.separator + "Info")) ; //NOI18N
}
else {
dir = new File( topDir.getAbsolutePath() + File.separator + "Info") ; //NOI18N
dir.renameTo( new File( topDir.getAbsolutePath() + File.separator + "Info_" + //NOI18N
locale)) ;
}
}
/** Get the localized version of the NBM filename. */
protected String getLocalizedFileName( String locale) {
return( baseFileName + "_" + locale + ".nbm") ; //NOI18N
}
protected String getLocales() {
if( locales != null) {
return( locales) ;
}
return( getGlobalProp( "locmakenbm.locales")) ; //NOI18N
}
/** See if there are any files for the given locale. */
protected boolean hasFilesInLocale( String loc) {
FileSet fs ;
boolean ret = true ;
// Setup a fileset to find files in this locale. //
fs = new FileSet() ;
fs.setDir( topDir) ;
addLocalePatterns( fs, loc) ;
// See if there are any localized files for this locale. //
String[] inc_files = fs.getDirectoryScanner(getProject()).getIncludedFiles();
if( inc_files.length == 0) {
ret = false ;
}
return( ret) ;
}
/** Add the patterns to include the localized files for the given locale. */
protected void addLocalePatterns( FileSet fs,
String loc) {
LinkedList<String> list = new LinkedList<>() ;
// Get the list of patterns for this locale. //
addLocalePatterns( list, loc) ;
for (String s: list) {
// Add it to the includes list. //
fs.createInclude().setName(s) ;
}
}
protected void addLocalePatterns( LinkedList<String> list,
String loc) {
// String dir = new String() ;
String re = new String() ;
// dir = mainDir ; // modified for clusterization
// re = dir + "/**/*_" + loc + ".*" ; // pattern is: ${dir}/**/*_${locale}.* //NOI18N
// list.add( new String( re)) ;
// re = dir + "/**/" + loc + "/" ; // pattern is: ${dir}/${locale}/ //NOI18N
// list.add( new String( re)) ;
re = "**/*_" + loc + ".*" ; // pattern is: ${dir}/**/*_${locale}.* //NOI18N
list.add(re) ;
re = "**/" + loc + "/" ; // pattern is: ${dir}/${locale}/ //NOI18N
list.add(re) ;
addLocIncludes( list, loc) ;
// For ja locale, include these other variants. //
if( loc.equals( "ja")) { //NOI18N
addLocalePatterns( list, "ja_JP.PCK") ; //NOI18N
addLocalePatterns( list, "ja_JP.eucJP") ; //NOI18N
addLocalePatterns( list, "ja_JP.SJIS") ; //NOI18N
addLocalePatterns( list, "ja_JP.UTF-8") ; //NOI18N
addLocalePatterns( list, "ja_JP.UTF8") ; //NOI18N
}
}
protected void addLocIncludes( LinkedList<String> list,
String loc) {
StringTokenizer tkzr ;
String locInc, incLocale, incPattern ;
int idx ;
if( locIncludes == null) {
return ;
}
// For each locale-specific include. //
tkzr = new StringTokenizer( locIncludes, ",\n\t ") ; //NOI18N
while( tkzr.hasMoreTokens()) {
locInc = tkzr.nextToken() ;
idx = locInc.indexOf( ":") ; //NOI18N
if( idx != -1) {
incLocale = locInc.substring( 0, idx) ;
incPattern = locInc.substring( idx+1) ;
if( incLocale.equals( loc)) {
list.add( incPattern) ;
}
}
else {
list.add( locInc) ;
}
}
}
protected String getGlobalProp( String name) {
String ret ;
ret = getProject().getProperty(name);
// Don't return empty strings or strings whose value contains a //
// property that isn't set. //
if( ret != null) {
if( ret.trim().equals( "")) { //NOI18N
ret = null ;
}
else if( ret.indexOf( "${") != -1) { //NOI18N
ret = null ;
}
}
return( ret) ;
}
protected String getKeystore() {
return( getGlobalProp( "locmakenbm.keystore")) ; //NOI18N
}
protected String getStorepass() {
return( getGlobalProp( "locmakenbm.storepass")) ; //NOI18N
}
protected String getAlias() {
return( getGlobalProp( "locmakenbm.alias")) ; //NOI18N
}
/** If the topDir doesn't exist, warn the user and return true. */
protected boolean printMissingDirWarning() {
boolean ret = false ;
if( !topDir.exists()) {
log( "WARNING: Skipping this task: Directory " + topDir.getPath() +
" doesn't exist.") ;
ret = true ;
}
return( ret) ;
}
/** If the localizing bundle is there, use it. */
protected void setLocBundle( MakeLNBM makenbm,
File bundle) {
if( bundle != null && bundle.exists()) {
makenbm.setLocBundle( bundle) ;
}
else {
log( "WARNING: Localizing bundle not found: " +
((bundle==null)?(""):(bundle.getPath())) ) ; //NOI18N
}
}
protected String getSrcDir( File file) {
InputStreamReader isr ;
FileInputStream fis ;
char[] buf = new char[ 200] ;
String s = null ;
int idx, len ;
try {
// Read the srcdir from the file that locjar wrote. //
fis = new FileInputStream( file) ;
isr = new InputStreamReader( fis) ;
len = isr.read( buf) ;
if( len != -1) {
if( buf[ len-1] == '\n') { //NOI18N
len-- ;
}
s = new String( buf, 0, len) ;
idx = s.indexOf( "=") ; //NOI18N
if( idx != -1) {
s = s.substring( idx + 1) ;
s.trim() ;
}
else {
s = null ;
}
}
}
catch( Exception e) {
System.out.println( "ERROR: " + e.getMessage()) ;
e.printStackTrace() ;
throw new BuildException() ;
}
return( s) ;
}
protected File findLocBundle( MakeLNBM makenbm,
String locale) {
File srcdirfile, locdir ;
int index ;
String s, srcdir = null ;
// See if the file containing the srcdir is there. //
srcdirfile = new File( topDir.getAbsolutePath() + File.separator +
"srcdir.properties") ; //NOI18N
if( srcdirfile.exists()) {
srcdir = getSrcDir( srcdirfile) ;
}
// if( srcdir == null) {
// throw new BuildException( "ERROR: Could not get source dir from: " + srcdirfile.getPath()) ;
// }
// Get the codename of this module. //
index = modInfo.indexOf( "/") ; //NOI18N
if( index != -1) {
s = modInfo.substring( 0, index) ;
}
else {
s = new String( modInfo) ;
}
// Convert to pathname and set the loc bundle. //
s = s.replace( '.', '/') ; //NOI18N
locdir = new File( getRelPath( srcdir + "/" + s, findLocBundle). //NOI18N
replace( '/', File.separatorChar)) ; //NOI18N
return( getDefaultLocBundleFile( locdir, locale)) ;
}
protected File getDefaultLocBundleFile( File dir,
String locale) {
return( new File( dir.getPath() + File.separator + "Bundle_" + locale + ".properties")) ; //NOI18N
}
protected File getSpecificLocBundleFile( File enBundle,
String locale) {
String path = enBundle.getPath() ;
int idx = path.lastIndexOf( '.') ; //NOI18N
if( idx != -1) {
return( new File( path.substring( 0, idx) + "_" + locale + path.substring( idx))) ; //NOI18N
}
else {
return( new File( path + "_" + locale)) ; //NOI18N
}
}
/** This supports ".." path elements at the start of path2. */
protected String getRelPath( String path1,
String path2) {
int idx1, idx2 ;
if( path2.equals( ".")) { //NOI18N
return( path1) ;
}
// For each ".." element in path2. //
while( true) {
idx2 = path2.indexOf( "..") ; //NOI18N
if( idx2 == -1) {
break ;
}
// Strip off the ".." //
path2 = path2.substring( 2) ;
// Strip off the slash if it starts with slash. //
idx2 = path2.indexOf( "/") ; //NOI18N
if( idx2 == 0) {
path2 = path2.substring( 1) ;
}
// Strip off the last element of path1. //
idx1 = path1.lastIndexOf( "/") ; //NOI18N
if( idx1 != -1) {
path1 = path1.substring( 0, idx1) ;
}
}
return( path1 + "/" + path2) ; //NOI18N
}
}