if (this.localeSourceFile == null) { throw new BuildException("Unable to find [de.enough.polish.util.Locale.java] in the path, please set the \"polishDir\"-attribute of the <build>-element correctly."); }
	private void initProject() {		// create debug manager:		boolean isDebugEnabled = this.buildSetting.isDebugEnabled(); 		DebugManager debugManager = null;		if (isDebugEnabled) {			try {				debugManager = new DebugManager( this.buildSetting.getDebugSetting() );			} catch (BuildException e) {				throw new BuildException( e.getMessage(), e );			}		}		// create project settings:		this.polishProject = new PolishProject( this.buildSetting.usePolishGui(), isDebugEnabled, debugManager );		if (debugManager != null && debugManager.isVerbose()) {			this.polishProject.addFeature("debugVerbose");		}		if (debugManager != null && this.buildSetting.getDebugSetting().showLogOnError()) {			this.polishProject.addFeature("showLogOnError");		}		this.polishProject.addCapability("license", this.infoSetting.getlicense() );		if (isDebugEnabled) {			this.polishProject.addFeature("debugEnabled");		}		// specify some preprocessing symbols depending on the selected features:		this.polishProject.addFeature(this.buildSetting.getImageLoadStrategy());		if (debugManager != null && this.buildSetting.getDebugSetting().useGui()) {			this.polishProject.addFeature("useDebugGui");		}		FullScreenSetting fullScreenSetting = this.buildSetting.getFullScreenSetting();		if (fullScreenSetting != null) {			if (fullScreenSetting.isMenu()) {				this.polishProject.addFeature("useMenuFullScreen");				this.polishProject.addFeature("useFullScreen");			} else if (fullScreenSetting.isEnabled()) {				this.polishProject.addFeature("useFullScreen");			}		}		// add all ant properties if desired: 		if (this.buildSetting.includeAntProperties()) {			Hashtable antProperties = this.project.getProperties();			Set keySet = antProperties.keySet();			for (Iterator iter = keySet.iterator(); iter.hasNext();) {				String key = (String) iter.next();				this.polishProject.addDirectCapability( key, (String) antProperties.get(key) );			}		}		// add all variables from the build.xml:		Variable[] variables = this.buildSetting.getVariables();		if (variables != null) {			ArrayList conditionalVarsList = new ArrayList();			for (int i = 0; i < variables.length; i++) {				Variable var = variables[i];				//System.out.println("adding variable [" + var.getName() + "]." );				if (var.hasCondition()) {					conditionalVarsList.add( var );				} else {					this.polishProject.addDirectCapability( var );				}			}			this.conditionalVariables = (Variable[]) conditionalVarsList.toArray( new Variable[ conditionalVarsList.size() ]); 		}		// add all symbols from the build.xml:		String symbolDefinition = this.buildSetting.getSymbols();		if (symbolDefinition != null) {			String[] symbols = TextUtil.splitAndTrim( symbolDefinition, ',' );			for (int i = 0; i < symbols.length; i++) {				this.polishProject.addDirectFeature( symbols[i] );			}		}				// create LibraryManager:		try {			this.libraryManager = new LibraryManager( this.project.getProperties(), this.buildSetting.getApiDir().getAbsolutePath(), this.wtkHome, this.buildSetting.getPreverify().getAbsolutePath(), this.buildSetting.openApis() );		} catch (JDOMException e) {			throw new BuildException("unable to create api manager: " + e.getMessage(), e );		} catch (IOException e) {			throw new BuildException("unable to create api manager: " + e.getMessage(), e );		} catch (InvalidComponentException e) {			throw new BuildException("unable to create api manager: " + e.getMessage(), e );		}		// create vendor/group/device manager:		try {			VendorManager vendorManager = new VendorManager( this.polishProject, this.buildSetting.openVendors());			DeviceGroupManager groupManager = new DeviceGroupManager( this.buildSetting.openGroups() ); 			this.deviceManager = new DeviceManager( vendorManager, groupManager, this.libraryManager, this.buildSetting.openDevices() );		} catch (JDOMException e) {			throw new BuildException("unable to create device manager: " + e.getMessage(), e );		} catch (IOException e) {			throw new BuildException("unable to create device manager: " + e.getMessage(), e );		} catch (InvalidComponentException e) {			throw new BuildException("unable to create device manager: " + e.getMessage(), e );		}				// create CSS attributes manager:		if (this.buildSetting.usePolishGui()) {			this.cssAttributesManager = new CssAttributesManager( this.buildSetting.openStandardCssAttributes() );			InputStream is = this.buildSetting.openCustomCssAttributes();			if (is != null) {				this.cssAttributesManager.addCssAttributes(is);			}		}				// create preprocessor:		this.preprocessor = new Preprocessor( this.polishProject, null, null, null, false, true, null );		// init line processors:		PreprocessorSetting[] settings = this.buildSetting.getPreprocessors();		CustomPreprocessor[] processors = new CustomPreprocessor[ settings.length + 1];		// add the default line processor:		CustomPreprocessor lineProcessor = new PolishPreprocessor();		lineProcessor.init(this.preprocessor);		processors[0] = lineProcessor;		for (int i = 0; i < settings.length; i++) {			PreprocessorSetting setting = settings[i];			processors[ i + 1] = CustomPreprocessor.getInstance(setting, this.preprocessor, this.project );		}		this.preprocessor.setCustomPreprocessors( processors );				//	initialise the preprocessing-source-directories:		DirectoryScanner dirScanner = new DirectoryScanner();		dirScanner.setIncludes( new String[]{"**/*.java"} );		File[] dirs = this.buildSetting.getSourceDirs();		this.sourceDirs = new File[ dirs.length];		this.sourceFiles = new TextFile[ dirs.length][];		if (this.buildSetting.getPolishDir() != null) {			// there is an explicit J2ME Polish directory:			this.polishSourceDir = this.buildSetting.getPolishDir();			dirScanner.setBasedir(this.polishSourceDir);			dirScanner.scan();			this.polishSourceFiles = getTextFiles( this.polishSourceDir,  dirScanner.getIncludedFiles() );		} else {			// the J2ME Polish sources need to be loaded from the jar-file:			long lastModificationTime = 0;			File jarFile = new File( this.buildSetting.getApiDir().getAbsolutePath() 					+ File.separator + "enough-j2mepolish-build.jar");			if (jarFile.exists()) {				lastModificationTime = jarFile.lastModified();			} else {				jarFile = new File("import/enough-j2mepolish-build.jar");				if (jarFile.exists()) {					lastModificationTime = jarFile.lastModified();				}			}			this.polishSourceDir = new File("src");			try {				String[] fileNames = this.resourceUtil.readTextFile( ".", "build/j2mepolish.index.txt");				this.polishSourceFiles = getTextFiles( "src", fileNames, lastModificationTime );			} catch (IOException e) {				throw new BuildException("Unable to load the J2ME source files from enough-j2mepolish-build.jar: " + e.getMessage(), e );			}		}				// load the normal source files:		for (int i = 0; i < dirs.length; i++) {			File dir = dirs[i];			if (!dir.exists()) {				throw new BuildException("The source-directory [" + dir.getAbsolutePath() + "] does not exist. Please check your settings in the [sourceDir] attribute of the <build> element.");			}			this.sourceDirs[i] = dir; 			dirScanner.setBasedir(dir);			dirScanner.scan();			this.sourceFiles[i] = getTextFiles( dir,  dirScanner.getIncludedFiles() );		}		if (this.buildSetting.usePolishGui() && this.styleSheetFile == null) {			throw new BuildException("Did not find the file [StyleSheet.java] of the J2ME Polish GUI framework. Please adjust the [polishDir] attribute of the <build> element in the [build.xml] file. The [polishDir]-attribute should point to the directory which contains the J2ME Polish-Java-sources.");		}				// load third party binary libraries, if any.		// When there are third party libraries, they will all be extracted		// and copied to the build/binary folder for easier integration:		File[] binaryLibraries = this.buildSetting.getBinaryLibraries();		if (binaryLibraries != null) {			File targetDir = new File( this.buildSetting.getWorkDir().getAbsolutePath() +					File.separatorChar + "binary");			String cacheDirName = this.buildSetting.getWorkDir().getAbsolutePath() +				File.separatorChar + "binarycache" + File.separatorChar;			this.binaryLibrariesDir = targetDir;			for (int i = 0; i < binaryLibraries.length; i++) {				File lib = binaryLibraries[i];				if (lib.isDirectory()) {					// a directory can contain library-files (jar, zip) as well					// as plain class or resource files. Each library-file					// will be extracted whereas other files will just be copied					// to the build/binary folder. 					DirectoryScanner binaryScanner = new DirectoryScanner();					binaryScanner.setBasedir( lib );					// just include all files in the directory:					binaryScanner.scan();					String[] includedFiles = binaryScanner.getIncludedFiles();					for (int j = 0; j < includedFiles.length; j++) {						String fileName = includedFiles[j];						File file = new File( lib.getAbsolutePath()								+ File.separatorChar + fileName );						if (fileName.endsWith(".zip") || fileName.endsWith(".jar")) {							// this is a library file:							// only extract it when the original is newer than the copy:							File cacheCopy = new File( cacheDirName + fileName );							if ( (!cacheCopy.exists())									|| (file.lastModified() > cacheCopy.lastModified())) {								this.binaryLibrariesUpdated = true;								try {									// copy the library to the cache:									FileUtil.copy(file, cacheCopy );									// unzip / unjar the content:									JarUtil.unjar(file, targetDir);								} catch (IOException e) {									e.printStackTrace();									throw new BuildException("Unable to extract the binary class files from the library [" + file.getAbsolutePath() + "]: " + e.toString(), e );								}															}						} else {							// this is a normal class or resource file:							try {								File targetFile = new File( targetDir.getAbsolutePath()										+ File.separatorChar + fileName );								// copy the file only when it is newer								// than the existing copy: 								if ( (!targetFile.exists()) 										|| (file.lastModified() > targetFile.lastModified()) ) {									this.binaryLibrariesUpdated = true;									FileUtil.copy(file, targetFile);								}							} catch (IOException e) {								e.printStackTrace();								throw new BuildException("Unable to copy the binary class files from the library [" + lib.getAbsolutePath() + "]: " + e.toString(), e );							}						}					}				} else {					// this is a library (jar or zip) file:					// copy only when the original is newer than the cached copy: 					File cacheCopy = new File( cacheDirName + lib.getName() );					if ( (!cacheCopy.exists())							|| (lib.lastModified() > cacheCopy.lastModified())) {						try {							this.binaryLibrariesUpdated = true;							// copy the library to the cache:							FileUtil.copy(lib, cacheCopy );							// unzip / unjar the content:							JarUtil.unjar(lib, targetDir);						} catch (IOException e) {							e.printStackTrace();							throw new BuildException("Unable to extract the binary class files from the library [" + lib.getAbsolutePath() + "]: " + e.toString(), e );						}											}				}			}		} // done preparing of binary libraries.				// init boot class path:		this.midp1BootClassPath = new Path( this.project, this.buildSetting.getMidp1Path().getAbsolutePath());		this.midp2BootClassPath = new Path( this.project, this.buildSetting.getMidp2Path().getAbsolutePath());		this.midp2Cldc11BootClassPath = new Path( this.project, this.buildSetting.getMidp2Cldc11Path().getAbsolutePath());				// init obfuscators:		if (this.buildSetting.doObfuscate()) {			ObfuscatorSetting[] obfuscatorSettings = this.buildSetting.getObfuscatorSettings();			ArrayList obfuscatorsList = new ArrayList();			String[] keepClasses = null;			for (int i = 0; i < obfuscatorSettings.length; i++) {				ObfuscatorSetting obfuscatorSetting = obfuscatorSettings[i];				if (keepClasses == null && 						obfuscatorSetting.hasKeepDefinitions()) {					keepClasses = obfuscatorSetting.getPreserveClassNames();				}				if ((obfuscatorSetting.isEnabled())) {					Obfuscator obfuscator = Obfuscator.getInstance( obfuscatorSetting, this.project, this.buildSetting.getApiDir(), this.libraryManager ); 					obfuscatorsList.add( obfuscator );				}							}			this.doObfuscate = (obfuscatorsList.size() > 0);			if (this.doObfuscate) {				this.obfuscators = (Obfuscator[]) obfuscatorsList.toArray( new Obfuscator[ obfuscatorsList.size() ] );				String[] midletClasses = this.buildSetting.getMidletClassNames();				if (keepClasses == null) {					keepClasses = new String[0];				}				this.preserveClasses = new String[ keepClasses.length + midletClasses.length ];				System.arraycopy( keepClasses, 0, this.preserveClasses, 0,  keepClasses.length );				System.arraycopy( midletClasses, 0, this.preserveClasses, keepClasses.length, midletClasses.length  );			}		}				// init import manager:		this.importConverter = new ImportConverter();				// init base style sheet:		if (this.buildSetting.usePolishGui()) {			ResourceSetting resourceSetting = this.buildSetting.getResourceSetting();			File cssFile = new File( resourceSetting.getDir().getAbsolutePath() + File.separatorChar + "polish.css");			if (!cssFile.exists()) {				log("Unable to find polish.css at [" + cssFile.getAbsolutePath() + "] - you should create this file when you want to make most of the J2ME Polish GUI.", Project.MSG_WARN );				this.styleSheet = new StyleSheet();			} else {				CssReader cssReader = new CssReader();				try {					cssReader.add(cssFile);				} catch (IOException e) {					throw new BuildException("Unable to load polish.css: " + e.getMessage(), e );				}				this.styleSheet = cssReader.getStyleSheet();			}		}				// set the names of the midlets:		this.midletClassesByName = new HashMap();		String[] midletClasses = this.buildSetting.getMidletClassNames();		for (int i = 0; i < midletClasses.length; i++) {			this.midletClassesByName.put( midletClasses[i], Boolean.TRUE );					}				// get the java-extension:		this.javaExtensions = this.buildSetting.getJavaExtensions();				// get the javac-settings:		this.javacTarget = this.buildSetting.getJavacTarget();				// get the resource manager:		this.resourceManager = new ResourceManager( this.buildSetting.getResourceSetting(), this.project, this.preprocessor.getBooleanEvaluator() );		this.supportedLocales = this.resourceManager.getLocales();		if (this.supportedLocales != null) {			// add the preprocessor for translations:			PreprocessorSetting setting = new PreprocessorSetting();			setting.setClass("de.enough.polish.preprocess.custom.TranslationPreprocessor");			this.translationPreprocessor = (TranslationPreprocessor) CustomPreprocessor.getInstance(setting, this.preprocessor, this.project);			this.preprocessor.addCustomPreprocessors( this.translationPreprocessor );		}				//check if there has been an error at the last run:		this.errorLock = new File( this.buildSetting.getWorkDir().getAbsolutePath()				+ File.separator + "error.lock");		if (this.errorLock.exists()) {			this.lastRunFailed = true;		} else {			this.lastRunFailed = false;			try {				this.errorLock.createNewFile();			} catch (IOException e) {				System.err.println("Warning: unable to create temporary lock file: " + e.toString() );			}		}				// set J2ME Polish specific logger,		// this logger will show the original source-code positions		// and remove some verbose logging from ProGuard etc:		Vector buildListeners = this.project.getBuildListeners();		BuildLogger logger = null;		for (Iterator iter = buildListeners.iterator(); iter.hasNext();) {			BuildListener listener = (BuildListener) iter.next();			if (listener instanceof BuildLogger) {				logger = (BuildLogger) listener;				break;			}					}		if (logger != null) {			// prepare the classPathTranslations-Map:			HashMap classPathTranslationsMap = new HashMap(); 			for (int i=0; i < this.sourceFiles.length; i++) {				TextFile[] files = this.sourceFiles[i];				for (int j = 0; j < files.length; j++) {					TextFile file = files[j];					classPathTranslationsMap.put( file.getFileName(), file.getFile().getAbsolutePath() );				}			}			this.polishLogger = new PolishLogger(logger, classPathTranslationsMap );			this.project.addBuildListener( this.polishLogger );			this.project.removeBuildListener(logger);		} else {			System.err.println("Warning: unable to replace Ant-logger. Compile errors will point to the preprocessed files instead of the original sources.");		}	}