this.name = deviceName; this.vendorName = vendor.getIdentifier();  addCapability(NAME, this.name); addCapability( "polish.name", this.name ); addCapability(VENDOR, this.vendorName); addCapability( "polish.vendor", this.vendorName ); addCapability(IDENTIFIER, this.identifier); addCapability( "polish.identifier", this.identifier );   String extendsStr = definition.getAttributeValue("extends"); if (extendsStr != null) { Device parentDevice = deviceManager.getDevice( extendsStr ); if (parentDevice == null) { throw new InvalidComponentException("Unable to load device [" + this.identifier + "]: the parent-device [" + extendsStr + "] is not known. Make sure it is defined before this device."); } addComponent(parentDevice); }   loadCapabilities(definition, this.identifier, "devices.xml");   ArrayList groupNamesList = new ArrayList(); ArrayList groupsList = new ArrayList(); String groupsDefinition = definition.getChildTextTrim("groups"); if (groupsDefinition != null && groupsDefinition.length() > 0) { String[] tempGroupNames = TextUtil.splitAndTrim(groupsDefinition, ','); for (int i = 0; i < tempGroupNames.length; i++) { String groupName = tempGroupNames[i]; DeviceGroup group = groupManager.getGroup(groupName); if (group == null) { throw new InvalidComponentException( "The device [" + this.identifier + "] contains the undefined group [" + groupName + "] - please check either [devices.xml] or [groups.xml]."); } addComponent(group); groupsList.add(group); groupNamesList.add(groupName); addFeature( "polish.group." + groupName ); } }    this.supportedApisString = getCapability(JAVA_PACKAGE); if (this.supportedApisString != null) {   String[] apis = TextUtil .splitAndTrim(this.supportedApisString, ','); for (int i = 0; i < apis.length; i++) { String api = apis[i].toLowerCase(); Library library = libraryManager.getLibrary(api); String symbol = api; if (library != null) { symbol = library.getSymbol(); } apis[i] = symbol; addFeature("api." + symbol); groupNamesList.add(symbol); groupsList.add(groupManager.getGroup(symbol, true));  if (library != null) { addComponent(library); } } this.supportedApis = apis; }  String soundFormatStr = getCapability(SOUND_FORMAT); if (soundFormatStr != null ) { String[] soundFormats = TextUtil.splitAndTrim(soundFormatStr.toLowerCase(), ','); for (int i = 0; i < soundFormats.length; i++) { String format = soundFormats[i]; addFeature( "polish.audio." + format ); groupNamesList.add( format ); groupsList.add(groupManager.getGroup(format, true)); } }  String videoFormatStr = getCapability(VIDEO_FORMAT); if (videoFormatStr != null ) { String[] videoFormats = TextUtil.splitAndTrim(videoFormatStr.toLowerCase(), ','); for (int i = 0; i < videoFormats.length; i++) { String format = videoFormats[i]; addFeature( "polish.video." + format ); groupNamesList.add( format ); groupsList.add(groupManager.getGroup(format, true)); } }  String midp = getCapability(JAVA_PLATFORM); if (midp == null) { throw new InvalidComponentException("The device [" + this.identifier + "] does not define the needed element [" + JAVA_PLATFORM + "]."); } midp = midp.toUpperCase(); if (midp.startsWith("MIDP/1.")) { addFeature("midp1"); this.midpVersion = MIDP_1; groupNamesList.add("midp1"); groupsList.add(groupManager.getGroup("midp1", true)); } else if (midp.startsWith("MIDP/2.")) { addFeature("midp2"); this.midpVersion = MIDP_2; groupNamesList.add("midp2"); groupsList.add(groupManager.getGroup("midp2", true)); } else { System.err.println("Warning: device [" + this.identifier + "] supports unknown JavaPlatform [" + midp + "]."); } String cldc = getCapability( JAVA_CONFIGURATION ); if (cldc != null) { cldc = cldc.toUpperCase(); if ("CLDC/1.0".equals( cldc)) { addFeature("cldc1.0"); groupNamesList.add("cldc1.0"); groupsList.add(groupManager.getGroup("cldc1.0", true)); this.isCldc10 = true; } else if ("CLDC/1.1".equals( cldc)) { addFeature("cldc1.1"); groupNamesList.add("cldc1.1"); groupsList.add(groupManager.getGroup("cldc1.1", true)); this.isCldc10 = false; } else if ("CLDC/1.0.4".equals( cldc)) { addFeature("cldc1.0"); addFeature("cldc1.0.4"); groupNamesList.add("cldc1.0"); groupsList.add(groupManager.getGroup("cldc1.0", true)); this.isCldc10 = true; } else { System.err.println("Warning: the device [" + this.identifier + "] supports the unknown JavaConfiguration [" + cldc + "."); }  } else { System.err.println("Warning: the device [" + this.identifier + "] has no JavaConfiguration defined."); } String supportsPolishGuiText = definition.getAttributeValue("supportsPolishGui"); if (supportsPolishGuiText != null) { supportsPolishGuiText = supportsPolishGuiText.toLowerCase(); this.supportsPolishGui = CastUtil.getBoolean(supportsPolishGuiText); } else {  this.supportsPolishGui = true;   String bitsPerPixelDef = getCapability(BITS_PER_PIXEL); if (bitsPerPixelDef != null) { try { int bitsPerPixel = Integer.parseInt(bitsPerPixelDef); this.supportsPolishGui = (bitsPerPixel >= POLISH_GUI_MIN_BITS_PER_PIXEL); } catch (NumberFormatException e) { throw new InvalidComponentException( "The device [" + this.identifier + "] contains the invalid BitsPerPixel-value [" + bitsPerPixelDef + "]: only integer values are allowed. Please correct this settings in the file [devices.xml]."); } }   String heapSizeStr = getCapability(HEAP_SIZE); if (heapSizeStr != null) { this.supportsPolishGui = POLISH_GUI_MIN_HEAP_SIZE .matches(heapSizeStr); } } if (this.supportsPolishGui) { addFeature(SUPPORTS_POLISH_GUI); } String bitsPerPixelStr = this.getCapability(BITS_PER_PIXEL); if (bitsPerPixelStr != null) { int bitsPerPixel = Integer.parseInt(bitsPerPixelStr); if (bitsPerPixel >= 4) { groupNamesList.add("BitsPerPixel.4+"); groupsList.add(groupManager.getGroup("BitsPerPixel.4+", true)); } if (bitsPerPixel >= 8) { groupNamesList.add("BitsPerPixel.8+"); groupsList.add(groupManager.getGroup("BitsPerPixel.8+", true)); } if (bitsPerPixel >= 12) { groupNamesList.add("BitsPerPixel.12+"); groupsList.add(groupManager.getGroup("BitsPerPixel.12+", true)); } if (bitsPerPixel >= 16) { groupNamesList.add("BitsPerPixel.16+"); groupsList.add(groupManager.getGroup("BitsPerPixel.16+", true)); } if (bitsPerPixel >= 18) { groupNamesList.add("BitsPerPixel.18+"); groupsList.add(groupManager.getGroup("BitsPerPixel.18+", true)); } if (bitsPerPixel >= 24) { groupNamesList.add("BitsPerPixel.24+"); groupsList.add(groupManager.getGroup("BitsPerPixel.24+", true)); } groupNamesList.add("BitsPerPixel." + bitsPerPixelStr); groupsList.add(groupManager.getGroup("BitsPerPixel." + bitsPerPixelStr, true));  }     if (this.midpVersion != MIDP_2 && !hasFeature("polish.supportSpriteTransformation")) { groupNamesList.add("NoSpriteTransformations"); groupsList.add(groupManager.getGroup("NoSpriteTransformations", true)); }  this.groupNames = (String[]) groupNamesList .toArray(new String[groupNamesList.size()]); this.groups = (DeviceGroup[]) groupsList .toArray(new DeviceGroup[groupsList.size()]);
	public Device(Element definition, String identifier, String deviceName,			Vendor vendor, DeviceGroupManager groupManager,			LibraryManager libraryManager,			DeviceManager deviceManager ) 	throws InvalidComponentException 	{		super(vendor);		this.identifier = identifier;		this.name = deviceName;		this.vendorName = vendor.getIdentifier();		addCapability(NAME, this.name);		addCapability( "polish.name", this.name );		addCapability(VENDOR, this.vendorName);		addCapability( "polish.vendor", this.vendorName );		addCapability(IDENTIFIER, this.identifier);		addCapability( "polish.identifier", this.identifier );				// check if this device extends another one:		String extendsStr = definition.getAttributeValue("extends");		if (extendsStr != null) {			Device parentDevice = deviceManager.getDevice( extendsStr );			if (parentDevice == null) {				throw new InvalidComponentException("Unable to load device [" + this.identifier + "]: the parent-device [" + extendsStr + "] is not known. Make sure it is defined before this device.");			}			addComponent(parentDevice);		}		// load capabilities and features:		loadCapabilities(definition, this.identifier, "devices.xml");		//add groups:		ArrayList groupNamesList = new ArrayList();		ArrayList groupsList = new ArrayList();		String groupsDefinition = definition.getChildTextTrim("groups");		if (groupsDefinition != null && groupsDefinition.length() > 0) {			String[] tempGroupNames = TextUtil.splitAndTrim(groupsDefinition, ',');			for (int i = 0; i < tempGroupNames.length; i++) {				String groupName = tempGroupNames[i];				DeviceGroup group = groupManager.getGroup(groupName);				if (group == null) {					throw new InvalidComponentException(							"The device ["									+ this.identifier									+ "] contains the undefined group ["									+ groupName									+ "] - please check either [devices.xml] or [groups.xml].");				}				addComponent(group);				groupsList.add(group);				groupNamesList.add(groupName);				addFeature( "polish.group." + groupName );			}		}		// set specific features:		// set api-support:		this.supportedApisString = getCapability(JAVA_PACKAGE);		if (this.supportedApisString != null) {			//System.out.println(this.identifier + " found apis: [" +			// supportedApisStr + "].");			String[] apis = TextUtil					.splitAndTrim(this.supportedApisString, ',');			for (int i = 0; i < apis.length; i++) {				String api = apis[i].toLowerCase();				Library library = libraryManager.getLibrary(api);				String symbol = api;				if (library != null) {					symbol = library.getSymbol();				}				apis[i] = symbol;				addFeature("api." + symbol);				groupNamesList.add(symbol);				groupsList.add(groupManager.getGroup(symbol, true));				// add any defined features and symbols of the api:				if (library != null) {					addComponent(library);				}			}			this.supportedApis = apis;		}		//set audio-support:		String soundFormatStr = getCapability(SOUND_FORMAT);		if (soundFormatStr != null ) {			String[] soundFormats = TextUtil.splitAndTrim(soundFormatStr.toLowerCase(), ',');			for (int i = 0; i < soundFormats.length; i++) {				String format = soundFormats[i];				addFeature( "polish.audio." + format );				groupNamesList.add( format );				groupsList.add(groupManager.getGroup(format, true));			}		}		//set video-support:		String videoFormatStr = getCapability(VIDEO_FORMAT);		if (videoFormatStr != null ) {			String[] videoFormats = TextUtil.splitAndTrim(videoFormatStr.toLowerCase(), ',');			for (int i = 0; i < videoFormats.length; i++) {				String format = videoFormats[i];				addFeature( "polish.video." + format );				groupNamesList.add( format );				groupsList.add(groupManager.getGroup(format, true));			}		}		// set midp-version:		String midp = getCapability(JAVA_PLATFORM);		if (midp == null) {			throw new InvalidComponentException("The device ["					+ this.identifier					+ "] does not define the needed element [" + JAVA_PLATFORM					+ "].");		}		midp = midp.toUpperCase();		if (midp.startsWith("MIDP/1.")) {			addFeature("midp1");			this.midpVersion = MIDP_1;			groupNamesList.add("midp1");			groupsList.add(groupManager.getGroup("midp1", true));		} else if (midp.startsWith("MIDP/2.")) {			addFeature("midp2");			this.midpVersion = MIDP_2;			groupNamesList.add("midp2");			groupsList.add(groupManager.getGroup("midp2", true));		} else {			System.err.println("Warning: device [" + this.identifier					+ "] supports unknown JavaPlatform [" + midp + "].");		}		String cldc = getCapability( JAVA_CONFIGURATION );		if (cldc != null) {			cldc = cldc.toUpperCase();			if ("CLDC/1.0".equals( cldc)) {				addFeature("cldc1.0");				groupNamesList.add("cldc1.0");				groupsList.add(groupManager.getGroup("cldc1.0", true));				this.isCldc10 = true;			} else if ("CLDC/1.1".equals( cldc)) {				addFeature("cldc1.1");				groupNamesList.add("cldc1.1");				groupsList.add(groupManager.getGroup("cldc1.1", true));				this.isCldc10 = false;			} else if ("CLDC/1.0.4".equals( cldc)) {				addFeature("cldc1.0");				addFeature("cldc1.0.4");				groupNamesList.add("cldc1.0");				groupsList.add(groupManager.getGroup("cldc1.0", true));				this.isCldc10 = true;			} else {				System.err.println("Warning: the device [" + this.identifier + 						"] supports the unknown JavaConfiguration [" + cldc + ".");			} 		} else {			System.err.println("Warning: the device [" + this.identifier 					+ "] has no JavaConfiguration defined.");		}		String supportsPolishGuiText = definition.getAttributeValue("supportsPolishGui");		if (supportsPolishGuiText != null) {			supportsPolishGuiText = supportsPolishGuiText.toLowerCase();			this.supportsPolishGui = CastUtil.getBoolean(supportsPolishGuiText);		} else {			// basically assume that any device supports the polish GUI:			this.supportsPolishGui = true;			// when a device has the BitsPerPixel capability defined,			// it needs to have at least 8 bits per pixel (= 2^8 == 256 colors)			String bitsPerPixelDef = getCapability(BITS_PER_PIXEL);			if (bitsPerPixelDef != null) {				try {					int bitsPerPixel = Integer.parseInt(bitsPerPixelDef);					this.supportsPolishGui = (bitsPerPixel >= POLISH_GUI_MIN_BITS_PER_PIXEL);				} catch (NumberFormatException e) {					throw new InvalidComponentException(							"The device ["									+ this.identifier									+ "] contains the invalid BitsPerPixel-value ["									+ bitsPerPixelDef									+ "]: only integer values are allowed. Please correct this settings in the file [devices.xml].");				}			}			// when the device has the heap size defined,			// it needs to have a minimum heap size of 500 kb:			String heapSizeStr = getCapability(HEAP_SIZE);			if (heapSizeStr != null) {				this.supportsPolishGui = POLISH_GUI_MIN_HEAP_SIZE						.matches(heapSizeStr);			}		}		if (this.supportsPolishGui) {			addFeature(SUPPORTS_POLISH_GUI);		}		String bitsPerPixelStr = this.getCapability(BITS_PER_PIXEL);		if (bitsPerPixelStr != null) {			int bitsPerPixel = Integer.parseInt(bitsPerPixelStr);			if (bitsPerPixel >= 4) {				groupNamesList.add("BitsPerPixel.4+");				groupsList.add(groupManager.getGroup("BitsPerPixel.4+", true));			}			if (bitsPerPixel >= 8) {				groupNamesList.add("BitsPerPixel.8+");				groupsList.add(groupManager.getGroup("BitsPerPixel.8+", true));			}			if (bitsPerPixel >= 12) {				groupNamesList.add("BitsPerPixel.12+");				groupsList.add(groupManager.getGroup("BitsPerPixel.12+", true));			}			if (bitsPerPixel >= 16) {				groupNamesList.add("BitsPerPixel.16+");				groupsList.add(groupManager.getGroup("BitsPerPixel.16+", true));			}			if (bitsPerPixel >= 18) {				groupNamesList.add("BitsPerPixel.18+");				groupsList.add(groupManager.getGroup("BitsPerPixel.18+", true));			}			if (bitsPerPixel >= 24) {				groupNamesList.add("BitsPerPixel.24+");				groupsList.add(groupManager.getGroup("BitsPerPixel.24+", true));			}			groupNamesList.add("BitsPerPixel." + bitsPerPixelStr);			groupsList.add(groupManager.getGroup("BitsPerPixel."					+ bitsPerPixelStr, true));		}				// add all devices which do not support sprite-transformations		// and which do not support the MIDP/2.0 standard to the		// NoSpriteTransformations-group:		if (this.midpVersion != MIDP_2 && !hasFeature("polish.supportSpriteTransformation")) {			groupNamesList.add("NoSpriteTransformations");			groupsList.add(groupManager.getGroup("NoSpriteTransformations", true));		}		this.groupNames = (String[]) groupNamesList				.toArray(new String[groupNamesList.size()]);		this.groups = (DeviceGroup[]) groupsList				.toArray(new DeviceGroup[groupsList.size()]);				}