You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by gb...@apache.org on 2011/12/07 20:14:06 UTC

svn commit: r1211604 [1/4] - in /pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox: ./ parser/ schema/ type/

Author: gbailleul
Date: Wed Dec  7 19:14:05 2011
New Revision: 1211604

URL: http://svn.apache.org/viewvc?rev=1211604&view=rev
Log:
PDFBOX-1186: Improve xmpbox code strength

* Preserve stack Trace
* System println
* Loose coupling
* avoid print stack trace
* Integer Instanciation
* Constructor calls overridable method 

Modified:
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/BuildPDFExtensionSchemaHelper.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/SaveMetadataHelper.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/XMPMetadata.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/DateConverter.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMPDocumentBuilder.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/PDFAExtensionSchema.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/PDFAIdentificationSchema.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/XMPBasicJobTicketSchema.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/schema/XMPSchema.java
    pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/type/DateType.java

Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/BuildPDFExtensionSchemaHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/BuildPDFExtensionSchemaHelper.java?rev=1211604&r1=1211603&r2=1211604&view=diff
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/BuildPDFExtensionSchemaHelper.java (original)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/BuildPDFExtensionSchemaHelper.java Wed Dec  7 19:14:05 2011
@@ -120,7 +120,7 @@ public class BuildPDFExtensionSchemaHelp
 								classSchem.getName(),
 								field.getName(),
 								"Couldn't read content, please check accessibility and declaration of field associated",
-								e.getCause());
+								e);
 					}
 					propExtDefAnnot = field
 							.getAnnotation(PropertyExtensionDefinition.class);
@@ -150,7 +150,7 @@ public class BuildPDFExtensionSchemaHelp
 					} catch (BadFieldValueException e) {
 						throw propertyDescriptionError(classSchem.getName(),
 								propName, "Wrong value for property Category",
-								e.getCause());
+								e);
 					}
 				}
 			}

Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/SaveMetadataHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/SaveMetadataHelper.java?rev=1211604&r1=1211603&r2=1211604&view=diff
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/SaveMetadataHelper.java (original)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/SaveMetadataHelper.java Wed Dec  7 19:14:05 2011
@@ -124,7 +124,7 @@ public class SaveMetadataHelper {
 		try {
 			XMLUtil.save(doc, os, "UTF-8");
 		} catch (TransformerException e) {
-			throw new TransformException("Failed to parse defined XMP");
+			throw new TransformException("Failed to parse defined XMP",e);
 		}
 
 	}
@@ -183,11 +183,11 @@ public class SaveMetadataHelper {
 			rdf.appendChild(schemContent);
 			XMLUtil.save(rdf, os, "UTF-8");
 		} catch (TransformerException e) {
-			throw new TransformException("Failed to parse defined XMP");
+			throw new TransformException("Failed to parse defined XMP",e);
 		} catch (IOException e) {
 			throw new TransformException(
 					"Failed to create Document to contain Schema representation ",
-					e.getCause());
+					e);
 		}
 
 	}

Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/XMPMetadata.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/XMPMetadata.java?rev=1211604&r1=1211603&r2=1211604&view=diff
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/XMPMetadata.java (original)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/XMPMetadata.java Wed Dec  7 19:14:05 2011
@@ -22,10 +22,9 @@ package org.apache.padaf.xmpbox;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-
+import java.util.Map;
 
 import org.apache.padaf.xmpbox.parser.XmpSchemaException;
 import org.apache.padaf.xmpbox.schema.AdobePDFSchema;
@@ -80,7 +79,7 @@ public class XMPMetadata {
             schemas = new SchemasContainer();
         } catch (IOException e) {
             throw new CreateXMPMetadataException(
-            "Failed to create Dom Document");
+            "Failed to create Dom Document",e);
         }
 
     }
@@ -112,7 +111,7 @@ public class XMPMetadata {
             schemas = new SchemasContainer();
         } catch (IOException e) {
             throw new CreateXMPMetadataException(
-            "Failed to create Dom Document");
+            "Failed to create Dom Document",e);
         }
     }
 
@@ -314,7 +313,7 @@ public class XMPMetadata {
      *             If namespaces list not contains PDF/A Extension namespace URI
      */
     public PDFAExtensionSchema createAndAddPDFAExtensionSchemaWithNS(
-            HashMap<String, String> namespaces) throws XmpSchemaException {
+           Map<String, String> namespaces) throws XmpSchemaException {
         PDFAExtensionSchema pdfAExt = new PDFAExtensionSchema(this, namespaces);
         pdfAExt.setAboutAsSimple("");
         addSchema(pdfAExt);

Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/DateConverter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/DateConverter.java?rev=1211604&r1=1211603&r2=1211604&view=diff
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/DateConverter.java (original)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/DateConverter.java Wed Dec  7 19:14:05 2011
@@ -40,204 +40,204 @@ import java.util.SimpleTimeZone;
  */
 public class DateConverter {
 
-	// The Date format is supposed to be the PDF_DATE_FORMAT, but not all PDF
-	// documents
-	// will use that date, so I have added a couple other potential formats
-	// to try if the original one does not work.
-	private static final SimpleDateFormat[] POTENTIAL_FORMATS = new SimpleDateFormat[] {
-			new SimpleDateFormat("EEEE, dd MMM yyyy hh:mm:ss a"),
-			new SimpleDateFormat("EEEE, MMM dd, yyyy hh:mm:ss a"),
-			new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"),
-			new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz") };
-
-	/**
-	 * According to check-style, Utility classes should not have a public or
-	 * default constructor.
-	 */
-	protected DateConverter() {
-	};
-
-	/**
-	 * This will convert a string to a calendar.
-	 * 
-	 * @param date
-	 *            The string representation of the calendar.
-	 * 
-	 * @return The calendar that this string represents.
-	 * 
-	 * @throws IOException
-	 *             If the date string is not in the correct format.
-	 */
-	public static Calendar toCalendar(String date) throws IOException {
-		Calendar retval = null;
-		if ((date != null) && (date.trim().length() > 0)) {
-			// these are the default values
-			int year = 0;
-			int month = 1;
-			int day = 1;
-			int hour = 0;
-			int minute = 0;
-			int second = 0;
-			// first string off the prefix if it exists
-			try {
-				SimpleTimeZone zone = null;
-				if (date.startsWith("D:")) {
-					date = date.substring(2, date.length());
-				}
-				date = date.replaceAll("[-:T]", "");
-
-				if (date.length() < 4) {
-					throw new IOException("Error: Invalid date format '" + date
-							+ "'");
-				}
-				year = Integer.parseInt(date.substring(0, 4));
-				if (date.length() >= 6) {
-					month = Integer.parseInt(date.substring(4, 6));
-				}
-				if (date.length() >= 8) {
-					day = Integer.parseInt(date.substring(6, 8));
-				}
-				if (date.length() >= 10) {
-					hour = Integer.parseInt(date.substring(8, 10));
-				}
-				if (date.length() >= 12) {
-					minute = Integer.parseInt(date.substring(10, 12));
-				}
-				if (date.length() >= 14) {
-					second = Integer.parseInt(date.substring(12, 14));
-				}
-				if (date.length() >= 15) {
-					char sign = date.charAt(14);
-					if (sign == 'Z') {
-						zone = new SimpleTimeZone(0, "Unknown");
-					} else {
-						int hours = 0;
-						int minutes = 0;
-						if (date.length() >= 17) {
-							if (sign == '+') {
-								// parseInt cannot handle the + sign
-								hours = Integer
-										.parseInt(date.substring(15, 17));
-							} else {
-								hours = -Integer.parseInt(date
-										.substring(14, 16));
-							}
-						}
-						if (sign == '+') {
-							if (date.length() >= 19) {
-								minutes = Integer.parseInt(date.substring(17,
-										19));
-							}
-						} else {
-							if (date.length() >= 18) {
-								minutes = Integer.parseInt(date.substring(16,
-										18));
-							}
-						}
-						zone = new SimpleTimeZone(hours * 60 * 60 * 1000
-								+ minutes * 60 * 1000, "Unknown");
-					}
-				}
-				if (zone == null) {
-					retval = new GregorianCalendar();
-				} else {
-					retval = new GregorianCalendar(zone);
-				}
-				retval.clear();
-				retval.set(year, month - 1, day, hour, minute, second);
-			} catch (NumberFormatException e) {
-
-				// remove the arbitrary : in the timezone. SimpleDateFormat
-				// can't handle it
-				if (date.substring(date.length() - 3, date.length() - 2)
-						.equals(":")
-						&& (date
-								.substring(date.length() - 6, date.length() - 5)
-								.equals("+") || date.substring(
-								date.length() - 6, date.length() - 5).equals(
-								"-"))) {
-					// thats a timezone string, remove the :
-					date = date.substring(0, date.length() - 3)
-							+ date.substring(date.length() - 2);
-				}
-				for (int i = 0; (retval == null)
-						&& (i < POTENTIAL_FORMATS.length); i++) {
-					try {
-						Date utilDate = POTENTIAL_FORMATS[i].parse(date);
-						retval = new GregorianCalendar();
-						retval.setTime(utilDate);
-					} catch (ParseException pe) {
-						// ignore and move to next potential format
-					}
-				}
-				if (retval == null) {
-					// we didn't find a valid date format so throw an exception
-					throw new IOException("Error converting date:" + date);
-				}
-			}
-		}
-		return retval;
-	}
-
-	/**
-	 * Append Zero to String Buffer before number < 10 ('1' become '01')
-	 * 
-	 * @param out
-	 *            The String buffer
-	 * @param number
-	 *            The concerned number
-	 */
-	private static void zeroAppend(StringBuffer out, int number) {
-		if (number < 10) {
-			out.append("0");
-		}
-		out.append(number);
-	}
-
-	/**
-	 * Convert the date to iso 8601 string format.
-	 * 
-	 * @param cal
-	 *            The date to convert.
-	 * @return The date represented as an ISO 8601 string.
-	 */
-	public static String toISO8601(Calendar cal) {
-		StringBuffer retval = new StringBuffer();
-
-		retval.append(cal.get(Calendar.YEAR));
-		retval.append("-");
-		zeroAppend(retval, cal.get(Calendar.MONTH) + 1);
-		retval.append("-");
-		zeroAppend(retval, cal.get(Calendar.DAY_OF_MONTH));
-		retval.append("T");
-		zeroAppend(retval, cal.get(Calendar.HOUR_OF_DAY));
-		retval.append(":");
-		zeroAppend(retval, cal.get(Calendar.MINUTE));
-		retval.append(":");
-		zeroAppend(retval, cal.get(Calendar.SECOND));
-
-		int timeZone = cal.get(Calendar.ZONE_OFFSET)
-				+ cal.get(Calendar.DST_OFFSET);
-		if (timeZone < 0) {
-			retval.append("-");
-		} else {
-			retval.append("+");
-		}
-		timeZone = Math.abs(timeZone);
-		// milliseconds/1000 = seconds = seconds / 60 = minutes = minutes/60 =
-		// hours
-		int hours = timeZone / 1000 / 60 / 60;
-		int minutes = (timeZone - (hours * 1000 * 60 * 60)) / 1000 / 1000;
-		if (hours < 10) {
-			retval.append("0");
-		}
-		retval.append(Integer.toString(hours));
-		retval.append(":");
-		if (minutes < 10) {
-			retval.append("0");
-		}
-		retval.append(Integer.toString(minutes));
+    // The Date format is supposed to be the PDF_DATE_FORMAT, but not all PDF
+    // documents
+    // will use that date, so I have added a couple other potential formats
+    // to try if the original one does not work.
+    private static final SimpleDateFormat[] POTENTIAL_FORMATS = new SimpleDateFormat[] {
+        new SimpleDateFormat("EEEE, dd MMM yyyy hh:mm:ss a"),
+        new SimpleDateFormat("EEEE, MMM dd, yyyy hh:mm:ss a"),
+        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"),
+        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz") };
+
+    /**
+     * According to check-style, Utility classes should not have a public or
+     * default constructor.
+     */
+    protected DateConverter() {
+    };
+
+    /**
+     * This will convert a string to a calendar.
+     * 
+     * @param date
+     *            The string representation of the calendar.
+     * 
+     * @return The calendar that this string represents.
+     * 
+     * @throws IOException
+     *             If the date string is not in the correct format.
+     */
+    public static Calendar toCalendar(String date) throws IOException {
+        Calendar retval = null;
+        if ((date != null) && (date.trim().length() > 0)) {
+            // these are the default values
+            int year = 0;
+            int month = 1;
+            int day = 1;
+            int hour = 0;
+            int minute = 0;
+            int second = 0;
+            // first string off the prefix if it exists
+            try {
+                SimpleTimeZone zone = null;
+                if (date.startsWith("D:")) {
+                    date = date.substring(2, date.length());
+                }
+                date = date.replaceAll("[-:T]", "");
+
+                if (date.length() < 4) {
+                    throw new IOException("Error: Invalid date format '" + date
+                            + "'");
+                }
+                year = Integer.parseInt(date.substring(0, 4));
+                if (date.length() >= 6) {
+                    month = Integer.parseInt(date.substring(4, 6));
+                }
+                if (date.length() >= 8) {
+                    day = Integer.parseInt(date.substring(6, 8));
+                }
+                if (date.length() >= 10) {
+                    hour = Integer.parseInt(date.substring(8, 10));
+                }
+                if (date.length() >= 12) {
+                    minute = Integer.parseInt(date.substring(10, 12));
+                }
+                if (date.length() >= 14) {
+                    second = Integer.parseInt(date.substring(12, 14));
+                }
+                if (date.length() >= 15) {
+                    char sign = date.charAt(14);
+                    if (sign == 'Z') {
+                        zone = new SimpleTimeZone(0, "Unknown");
+                    } else {
+                        int hours = 0;
+                        int minutes = 0;
+                        if (date.length() >= 17) {
+                            if (sign == '+') {
+                                // parseInt cannot handle the + sign
+                                hours = Integer
+                                .parseInt(date.substring(15, 17));
+                            } else {
+                                hours = -Integer.parseInt(date
+                                        .substring(14, 16));
+                            }
+                        }
+                        if (sign == '+') {
+                            if (date.length() >= 19) {
+                                minutes = Integer.parseInt(date.substring(17,
+                                        19));
+                            }
+                        } else {
+                            if (date.length() >= 18) {
+                                minutes = Integer.parseInt(date.substring(16,
+                                        18));
+                            }
+                        }
+                        zone = new SimpleTimeZone(hours * 60 * 60 * 1000
+                                + minutes * 60 * 1000, "Unknown");
+                    }
+                }
+                if (zone == null) {
+                    retval = new GregorianCalendar();
+                } else {
+                    retval = new GregorianCalendar(zone);
+                }
+                retval.clear();
+                retval.set(year, month - 1, day, hour, minute, second);
+            } catch (NumberFormatException e) {
+
+                // remove the arbitrary : in the timezone. SimpleDateFormat
+                // can't handle it
+                if (date.substring(date.length() - 3, date.length() - 2)
+                        .equals(":")
+                        && (date
+                                .substring(date.length() - 6, date.length() - 5)
+                                .equals("+") || date.substring(
+                                        date.length() - 6, date.length() - 5).equals(
+                                        "-"))) {
+                    // thats a timezone string, remove the :
+                    date = date.substring(0, date.length() - 3)
+                    + date.substring(date.length() - 2);
+                }
+                for (int i = 0; (retval == null)
+                && (i < POTENTIAL_FORMATS.length); i++) {
+                    try {
+                        Date utilDate = POTENTIAL_FORMATS[i].parse(date);
+                        retval = new GregorianCalendar();
+                        retval.setTime(utilDate);
+                    } catch (ParseException pe) {
+                        // ignore and move to next potential format
+                    }
+                }
+                if (retval == null) {
+                    // we didn't find a valid date format so throw an exception
+                    throw new IOException("Error converting date:" + date,e);
+                }
+            }
+        }
+        return retval;
+    }
+
+    /**
+     * Append Zero to String Buffer before number < 10 ('1' become '01')
+     * 
+     * @param out
+     *            The String buffer
+     * @param number
+     *            The concerned number
+     */
+    private static void zeroAppend(StringBuffer out, int number) {
+        if (number < 10) {
+            out.append("0");
+        }
+        out.append(number);
+    }
+
+    /**
+     * Convert the date to iso 8601 string format.
+     * 
+     * @param cal
+     *            The date to convert.
+     * @return The date represented as an ISO 8601 string.
+     */
+    public static String toISO8601(Calendar cal) {
+        StringBuffer retval = new StringBuffer();
+
+        retval.append(cal.get(Calendar.YEAR));
+        retval.append("-");
+        zeroAppend(retval, cal.get(Calendar.MONTH) + 1);
+        retval.append("-");
+        zeroAppend(retval, cal.get(Calendar.DAY_OF_MONTH));
+        retval.append("T");
+        zeroAppend(retval, cal.get(Calendar.HOUR_OF_DAY));
+        retval.append(":");
+        zeroAppend(retval, cal.get(Calendar.MINUTE));
+        retval.append(":");
+        zeroAppend(retval, cal.get(Calendar.SECOND));
+
+        int timeZone = cal.get(Calendar.ZONE_OFFSET)
+        + cal.get(Calendar.DST_OFFSET);
+        if (timeZone < 0) {
+            retval.append("-");
+        } else {
+            retval.append("+");
+        }
+        timeZone = Math.abs(timeZone);
+        // milliseconds/1000 = seconds = seconds / 60 = minutes = minutes/60 =
+        // hours
+        int hours = timeZone / 1000 / 60 / 60;
+        int minutes = (timeZone - (hours * 1000 * 60 * 60)) / 1000 / 1000;
+        if (hours < 10) {
+            retval.append("0");
+        }
+        retval.append(Integer.toString(hours));
+        retval.append(":");
+        if (minutes < 10) {
+            retval.append("0");
+        }
+        retval.append(Integer.toString(minutes));
 
-		return retval.toString();
-	}
+        return retval.toString();
+    }
 }

Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java?rev=1211604&r1=1211603&r2=1211604&view=diff
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java (original)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/NSMapping.java Wed Dec  7 19:14:05 2011
@@ -57,470 +57,462 @@ import org.apache.padaf.xmpbox.schema.XM
  */
 public class NSMapping {
 
-	public static final List<String> BASIC_TYPES;
-	public static final HashMap<String, String> COMPLEX_BASIC_TYPES;
+    public static final List<String> BASIC_TYPES;
+    public static final Map<String, String> COMPLEX_BASIC_TYPES;
 
-	static {
-		BASIC_TYPES = new ArrayList<String>();
-		BASIC_TYPES.add("Text");
-		BASIC_TYPES.add("ProperName");
-		BASIC_TYPES.add("Integer");
-		BASIC_TYPES.add("Boolean");
-		BASIC_TYPES.add("Date");
-		BASIC_TYPES.add("URI");
-		BASIC_TYPES.add("URL");
-		BASIC_TYPES.add("bag Text");
-		BASIC_TYPES.add("bag ProperName");
-		BASIC_TYPES.add("bag Xpath");
-		BASIC_TYPES.add("seq Text");
-		BASIC_TYPES.add("seq Field");
-		BASIC_TYPES.add("seq Date");
-		BASIC_TYPES.add("Lang Alt");
-
-		COMPLEX_BASIC_TYPES = new HashMap<String, String>();
-		COMPLEX_BASIC_TYPES.put("http://ns.adobe.com/xap/1.0/g/img/",
-				"Thumbnail");
-		COMPLEX_BASIC_TYPES.put(PhotoshopSchema.PHOTOSHOPURI,
-				"TextLayers");
-		COMPLEX_BASIC_TYPES.put(XMPBasicJobTicketSchema.JOB_TICKET_URI, "Job");
-	}
-
-	protected Map<String, XMPSchemaFactory> nsMaps;
-	protected Map<String, String> complexBasicTypesDeclarationEntireXMPLevel;
-	protected Map<String, String> complexBasicTypesDeclarationSchemaLevel;
-	protected Map<String, String> complexBasicTypesDeclarationPropertyLevel;
-
-	/**
-	 * Constructor of the NameSpace mapping
-	 * 
-	 * @throws XmpSchemaException
-	 *             When could not read a property data in a Schema Class given
-	 */
-	public NSMapping() throws XmpSchemaException {
-		nsMaps = new HashMap<String, XMPSchemaFactory>();
-		complexBasicTypesDeclarationEntireXMPLevel = new HashMap<String, String>();
-		complexBasicTypesDeclarationSchemaLevel = new HashMap<String, String>();
-		complexBasicTypesDeclarationPropertyLevel = new HashMap<String, String>();
-		init();
-
-	}
-
-
-	/**
-	 * Import an NSMapping content.
-	 * @param imp
-	 */
-	public void importNSMapping(NSMapping imp) throws XmpSchemaException {
-		mergeNSMap(imp.nsMaps);
-		mergeComplexBasicTypesDeclarationEntireXMPLevel(imp.complexBasicTypesDeclarationEntireXMPLevel);
-		mergeComplexBasicTypesDeclarationSchemaLevel(imp.complexBasicTypesDeclarationSchemaLevel);
-		mergeComplexBasicTypesDeclarationPropertyLevel(imp.complexBasicTypesDeclarationPropertyLevel);
-	}
-	
-	protected void mergeNSMap(Map<String, XMPSchemaFactory> map) throws XmpSchemaException {
-		for (Entry<String, XMPSchemaFactory> entry : map.entrySet() ) {
-			if (this.nsMaps.containsKey(entry.getKey())) {
-				this.nsMaps.get(entry.getKey()).importXMPSchemaFactory(entry.getValue());
-			} else {
-				this.nsMaps.put(entry.getKey(), entry.getValue());
-			}
-		}
-	}
-	
-	private void mergeComplexBasicTypesDeclarationEntireXMPLevel(Map<String, String> external) {
-		for (Entry<String, String> entry : external.entrySet()) {
-			if(!complexBasicTypesDeclarationEntireXMPLevel.containsKey(entry.getKey())) {
-				complexBasicTypesDeclarationEntireXMPLevel.put(entry.getKey(), entry.getValue());
-			}
-		}
-	}
-	
-	private void mergeComplexBasicTypesDeclarationSchemaLevel(Map<String, String> external) {
-		for (Entry<String, String> entry : external.entrySet()) {
-			if(!complexBasicTypesDeclarationSchemaLevel.containsKey(entry.getKey())) {
-				complexBasicTypesDeclarationSchemaLevel.put(entry.getKey(), entry.getValue());
-			}
-		}
-	}
-
-	private void mergeComplexBasicTypesDeclarationPropertyLevel(Map<String, String> external) {
-		for (Entry<String, String> entry : external.entrySet()) {
-			if(!complexBasicTypesDeclarationPropertyLevel.containsKey(entry.getKey())) {
-				complexBasicTypesDeclarationPropertyLevel.put(entry.getKey(), entry.getValue());
-			}
-		}
-	}
-
-	/**
-	 * Add mapping of common schemas
-	 * 
-	 * @throws XmpSchemaException
-	 *             When could not read a property data in a Schema Class given
-	 */
-	private void init() throws XmpSchemaException {
-		addNameSpace("http://ns.adobe.com/xap/1.0/", XMPBasicSchema.class);
-		addNameSpace("http://purl.org/dc/elements/1.1/", DublinCoreSchema.class);
-		addNameSpace("http://www.aiim.org/pdfa/ns/extension/", PDFAExtensionSchema.class);
-		addNameSpace("http://ns.adobe.com/xap/1.0/mm/",	XMPMediaManagementSchema.class);
-		addNameSpace("http://ns.adobe.com/pdf/1.3/", AdobePDFSchema.class);
-		addNameSpace("http://www.aiim.org/pdfa/ns/id/",	PDFAIdentificationSchema.class);
-		addNameSpace("http://ns.adobe.com/xap/1.0/rights/",	XMPRightsManagementSchema.class);
-		addNameSpace(PhotoshopSchema.PHOTOSHOPURI,	PhotoshopSchema.class);
-		addNameSpace(XMPBasicJobTicketSchema.JOB_TICKET_URI,XMPBasicJobTicketSchema.class);
-	}
-
-	/**
-	 * Add a namespace declaration and Schema factory associated
-	 * 
-	 * @param ns
-	 *            the Namespace URI
-	 * @param classSchem
-	 *            The class representation of the schema linked to the namespace
-	 * @throws XmpSchemaException
-	 *             When could not read property name in Schema Class given
-	 */
-	protected void addNameSpace(String ns, Class<? extends XMPSchema> classSchem)
-			throws XmpSchemaException {
-		nsMaps.put(ns, new XMPSchemaFactory(ns, classSchem,	initializePropMapping(ns, classSchem)));
-	}
-
-	/**
-	 * Initialize the Property Mapping for a given schema
-	 * 
-	 * @param ns
-	 *            Namespace URI
-	 * @param classSchem
-	 *            The class representation of the schema linked to the namespace
-	 * @return Construct expected properties types representation
-	 * @throws XmpSchemaException
-	 *             When could not read property name in field with properties
-	 *             annotations
-	 */
-	private PropMapping initializePropMapping(String ns,
-			Class<? extends XMPSchema> classSchem) throws XmpSchemaException {
-		PropertyType propType;
-		PropertyAttributesAnnotation propAtt;
-		Field[] fields;
-		PropMapping propMap = new PropMapping(ns);
-		fields = classSchem.getFields();
-		String propName = null;
-		for (Field field : fields) {
-			if (field.isAnnotationPresent(PropertyType.class)) {
-				try {
-					propName = (String) field.get(propName);
-				} catch (Exception e) {
-					throw new XmpSchemaException(
-							"couldn't read one type declaration, please check accessibility and declaration of fields annoted in "
-									+ classSchem.getName(), e.getCause());
-				}
-				// System.out.println("nameField:"+propName);
-				propType = field.getAnnotation(PropertyType.class);
-				// System.out.println("Type '"+propInfo.propertyType()+"' defined for "+propName);
-				if (!field
-						.isAnnotationPresent(PropertyAttributesAnnotation.class)) {
-					propMap.addNewProperty(propName, propType.propertyType(),
-							null);
-				} else {
-					// TODO Case where a special annotation is used to specify
-					// attributes
-					// NOT IMPLEMENTED YET, JUST TO GIVE A CLUE TO MAKE THIS
-					propAtt = field
-							.getAnnotation(PropertyAttributesAnnotation.class);
-					List<String> attributes = new ArrayList<String>();
-					for (String att : propAtt.expectedAttributes()) {
-						attributes.add(att);
-					}
-					propMap.addNewProperty(propName, propType.propertyType(),
-							attributes);
-				}
-			}
-		}
-		return propMap;
-	}
-
-	/**
-	 * see if a specific type is known as a basic XMP type
-	 * 
-	 * @param type
-	 *            Type to check
-	 * @return True if type is a simple basic type
-	 */
-	private boolean isBasicType(String type) {
-		return BASIC_TYPES.contains(type);
-
-	}
-
-	/**
-	 * Say if a specific namespace is known
-	 * 
-	 * @param namespace
-	 *            The namespace URI checked
-	 * @return True if namespace URI is known
-	 */
-	public boolean isContainedNamespace(String namespace) {
-		return nsMaps.containsKey(namespace);
-	}
-
-	/**
-	 * Give type of specified property in specified schema (given by its
-	 * namespaceURI)
-	 * 
-	 * @param namespace
-	 *            The namespaceURI to explore
-	 * @param prop
-	 *            the property Qualified Name
-	 * @return Property type declared for namespace specified, null if unknown
-	 */
-	public String getSpecifiedPropertyType(String namespace, QName prop) {
-		if (nsMaps.containsKey(namespace)) {
-			return nsMaps.get(namespace).getPropertyType(prop.getLocalPart());
-		}
-		// check if its a complexbasicValueType and if it's has been declared
-		return getComplexBasicValueTypeEffectiveType(prop.getPrefix());
-
-	}
-
-	/**
-	 * Check if a non basic value type used is describes in the schema which
-	 * inlude a property with a such type
-	 * 
-	 * @param desc
-	 *            The schema description associated to the schema which declare
-	 *            a property with specific value type
-	 * @param definedValueType
-	 *            The value type name to find in value types descriptions
-	 * @return The description of this specific value type
-	 * @throws XmpUnknownValueTypeException
-	 *             If no declaration found
-	 */
-	private PDFAValueTypeDescription findValueTypeDescription(
-			SchemaDescription desc, String definedValueType)
-			throws XmpUnknownValueTypeException {
-		List<PDFAValueTypeDescription> values = desc.getValueTypes();
-		for (PDFAValueTypeDescription val : values) {
-			if (definedValueType.equals(val.getTypeNameValue())) {
-				return val;
-			}
-		}
-		throw new XmpUnknownValueTypeException("ValueType '" + definedValueType
-				+ "' is unknown. no declaration found in this schema");
-	}
-
-	/**
-	 * Check if valueType used for a specified property description is known (in
-	 * case where it's a normal value type or if a value type which has been
-	 * defined in PDF/A Extension schema)
-	 * 
-	 * @param desc
-	 *            The schema description associated to the schema which declare
-	 *            a property with specific value type
-	 * @param definedValueType
-	 *            The value type name to find in value types descriptions
-	 * @return value type equivalence (value type which can be treat (orginal
-	 *         basic value type or specific value type decomposed to find basic
-	 *         types)
-	 * @throws XmpUnknownValueTypeException
-	 *             When Value Type is unknown
-	 * 
-	 */
-	private String getValueTypeEquivalence(SchemaDescription desc,
-			String definedValueType) throws XmpUnknownValueTypeException {
-		if (isBasicType(definedValueType)) {
-			return definedValueType;
-		}
-		PDFAValueTypeDescription val = findValueTypeDescription(desc,
-				definedValueType);
-		if (val.getFields().isEmpty()) {
-			// if fields value are note defined we suppose the property is a
-			// Text type
-			return "Text";
-		}
-		return "Field";
-	}
-
-	/**
-	 * . For a specific valuetype declared in this schema. This method decompose
-	 * it if field are present. and add types expected
-	 * 
-	 * @param desc
-	 *            The schema description associated to the schema which declare
-	 *            a property with specific value type
-	 * @param valueType
-	 *            valueType to analyze
-	 * @param prop
-	 *            Expected properties types representation
-	 * @throws XmpUnknownValueTypeException
-	 *             When a Value Type associated is unknown
-	 */
-	private void declareAssociatedFieldType(SchemaDescription desc,
-			String valueType, PropMapping prop)
-			throws XmpUnknownValueTypeException {
-
-		PDFAValueTypeDescription val = findValueTypeDescription(desc, valueType);
-		for (PDFAFieldDescription field : val.getFields()) {
-			// TODO case where a field call another nspace property ???
-			String fieldType = getValueTypeEquivalence(desc, field
-					.getValueTypeValue());
-			if (fieldType.equals("Field")) {
-				throw new XmpUnknownValueTypeException(
-						"ValueType Field reference a valuetype unknown");
-			}
-			prop.addNewProperty(field.getNameValue(), fieldType, null);
-
-		}
-	}
-
-	/**
-	 * Add a new namespace Mapping for specific schema declared in PDF/A
-	 * Extension schema
-	 * 
-	 * @param desc
-	 *            The schemaDescription associated to the schema
-	 * @throws XmpUnknownValueTypeException
-	 *             When a Value Type associated is unknown
-	 */
-	public void setNamespaceDefinition(SchemaDescription desc)
-			throws XmpUnknownValueTypeException {
-		PropMapping propMap = new PropMapping(desc.getNameSpaceURI());
-		List<PDFAPropertyDescription> props = desc.getProperties();
-		for (int i = 0; i < props.size(); i++) {
-			String type = getValueTypeEquivalence(desc, props.get(i).getValueTypeValue());
-			propMap.addNewProperty(props.get(i).getNameValue(), type, null);
-			if (type.equals("Field")) {
-				declareAssociatedFieldType(desc, props.get(i).getValueTypeValue(), propMap);
-			}
-		}
-		String nsName = desc.getPrefix();
-		String ns = desc.getNameSpaceURI();
-		nsMaps.put(ns, new XMPSchemaFactory(nsName, ns, XMPSchema.class, propMap));
-	}
-
-	/**
-	 * Return the specialized schema class representation if it's known (create
-	 * and add it to metadata). In other cases, return null
-	 * 
-	 * @param metadata
-	 *            Metadata to link the new schema
-	 * @param namespace
-	 *            The namespace URI
-	 * @return Schema representation
-	 * @throws XmpSchemaException
-	 *             When Instancing specified Object Schema failed
-	 */
-	public XMPSchema getAssociatedSchemaObject(XMPMetadata metadata, String namespace, String prefix) throws XmpSchemaException {
-		if (!nsMaps.containsKey(namespace)) {
-			return null;
-		}
-		XMPSchemaFactory factory = nsMaps.get(namespace);
-		return factory.createXMPSchema(metadata, prefix);
-	}
-
-	/**
-	 * Check if a namespace used reference a complex basic types (like
-	 * Thumbnails)
-	 * 
-	 * @param namespace
-	 *            The namespace URI to check
-	 * @return True if namespace URI is a reference for a complex basic type
-	 */
-	public boolean isComplexBasicTypes(String namespace) {
-		return COMPLEX_BASIC_TYPES.containsKey(namespace);
-	}
-
-	/**
-	 * Check if a namespace declaration for a complex basic type has been found
-	 * and if its valid for the entire XMP stream
-	 * 
-	 * @param namespace
-	 *            the namespace URI
-	 * @param prefix
-	 *            the prefix associated to this namespace
-	 */
-	public void setComplexBasicTypesDeclarationForLevelXMP(String namespace,
-			String prefix) {
-		if (isComplexBasicTypes(namespace)) {
-			complexBasicTypesDeclarationEntireXMPLevel.put(prefix, namespace);
-		}
-	}
-
-	/**
-	 * Check if a namespace declaration for a complex basic type has been found
-	 * and if its valid for the current schema description (at level of
-	 * rdf:Description)
-	 * 
-	 * @param namespace
-	 *            the namespace URI
-	 * @param prefix
-	 *            the prefix associated to this namespace
-	 */
-	public void setComplexBasicTypesDeclarationForLevelSchema(String namespace,
-			String prefix) {
-		if (isComplexBasicTypes(namespace)) {
-			complexBasicTypesDeclarationSchemaLevel.put(prefix, namespace);
-		}
-
-	}
-
-	/**
-	 * Check if a namespace declaration for a complex basic type has been found
-	 * and if its valid for the current property description
-	 * 
-	 * @param namespace
-	 *            the namespace URI
-	 * @param prefix
-	 *            the prefix associated to this namespace
-	 */
-	public void setComplexBasicTypesDeclarationForLevelProperty(
-			String namespace, String prefix) {
-		if (isComplexBasicTypes(namespace)) {
-			complexBasicTypesDeclarationPropertyLevel.put(prefix, namespace);
-		}
-	}
-
-	/**
-	 * Check for all XMP level if a complexBasicValueType prefix has been
-	 * declared
-	 * 
-	 * @param prefix
-	 *            The prefix which may design the namespace URI of the complex
-	 *            basic type
-	 * @return The type if it is known, else null.
-	 */
-	public String getComplexBasicValueTypeEffectiveType(String prefix) {
-		if (complexBasicTypesDeclarationPropertyLevel.containsKey(prefix)) {
-			return COMPLEX_BASIC_TYPES
-					.get(complexBasicTypesDeclarationPropertyLevel.get(prefix));
-		}
-		if (complexBasicTypesDeclarationSchemaLevel.containsKey(prefix)) {
-			return COMPLEX_BASIC_TYPES
-					.get(complexBasicTypesDeclarationSchemaLevel.get(prefix));
-		}
-		if (complexBasicTypesDeclarationEntireXMPLevel.containsKey(prefix)) {
-			return COMPLEX_BASIC_TYPES
-					.get(complexBasicTypesDeclarationEntireXMPLevel.get(prefix));
-		}
-		return null;
-	}
-
-	/**
-	 * Reset complex Basic types declaration for property level
-	 */
-	public void resetComplexBasicTypesDeclarationInPropertyLevel() {
-		complexBasicTypesDeclarationPropertyLevel.clear();
-	}
-
-	/**
-	 * Reset complex Basic types declaration for schema level
-	 */
-	public void resetComplexBasicTypesDeclarationInSchemaLevel() {
-		complexBasicTypesDeclarationSchemaLevel.clear();
-	}
-
-	/**
-	 * Reset complex Basic types declaration for Entire XMP level
-	 */
-	public void resetComplexBasicTypesDeclarationInEntireXMPLevel() {
-		complexBasicTypesDeclarationEntireXMPLevel.clear();
-	}
+    static {
+        BASIC_TYPES = new ArrayList<String>();
+        BASIC_TYPES.add("Text");
+        BASIC_TYPES.add("ProperName");
+        BASIC_TYPES.add("Integer");
+        BASIC_TYPES.add("Boolean");
+        BASIC_TYPES.add("Date");
+        BASIC_TYPES.add("URI");
+        BASIC_TYPES.add("URL");
+        BASIC_TYPES.add("bag Text");
+        BASIC_TYPES.add("bag ProperName");
+        BASIC_TYPES.add("bag Xpath");
+        BASIC_TYPES.add("seq Text");
+        BASIC_TYPES.add("seq Field");
+        BASIC_TYPES.add("seq Date");
+        BASIC_TYPES.add("Lang Alt");
+
+        COMPLEX_BASIC_TYPES = new HashMap<String, String>();
+        COMPLEX_BASIC_TYPES.put("http://ns.adobe.com/xap/1.0/g/img/",
+        "Thumbnail");
+        COMPLEX_BASIC_TYPES.put(PhotoshopSchema.PHOTOSHOPURI,
+        "TextLayers");
+        COMPLEX_BASIC_TYPES.put(XMPBasicJobTicketSchema.JOB_TICKET_URI, "Job");
+    }
+
+    protected Map<String, XMPSchemaFactory> nsMaps;
+    protected Map<String, String> complexBasicTypesDeclarationEntireXMPLevel;
+    protected Map<String, String> complexBasicTypesDeclarationSchemaLevel;
+    protected Map<String, String> complexBasicTypesDeclarationPropertyLevel;
+
+    /**
+     * Constructor of the NameSpace mapping
+     * 
+     * @throws XmpSchemaException
+     *             When could not read a property data in a Schema Class given
+     */
+    public NSMapping() throws XmpSchemaException {
+        nsMaps = new HashMap<String, XMPSchemaFactory>();
+        complexBasicTypesDeclarationEntireXMPLevel = new HashMap<String, String>();
+        complexBasicTypesDeclarationSchemaLevel = new HashMap<String, String>();
+        complexBasicTypesDeclarationPropertyLevel = new HashMap<String, String>();
+        //  Add mapping of common schemas
+        addNameSpace("http://ns.adobe.com/xap/1.0/", XMPBasicSchema.class);
+        addNameSpace("http://purl.org/dc/elements/1.1/", DublinCoreSchema.class);
+        addNameSpace("http://www.aiim.org/pdfa/ns/extension/", PDFAExtensionSchema.class);
+        addNameSpace("http://ns.adobe.com/xap/1.0/mm/", XMPMediaManagementSchema.class);
+        addNameSpace("http://ns.adobe.com/pdf/1.3/", AdobePDFSchema.class);
+        addNameSpace("http://www.aiim.org/pdfa/ns/id/", PDFAIdentificationSchema.class);
+        addNameSpace("http://ns.adobe.com/xap/1.0/rights/",     XMPRightsManagementSchema.class);
+        addNameSpace(PhotoshopSchema.PHOTOSHOPURI,      PhotoshopSchema.class);
+        addNameSpace(XMPBasicJobTicketSchema.JOB_TICKET_URI,XMPBasicJobTicketSchema.class);
+
+
+    }
+
+
+    /**
+     * Import an NSMapping content.
+     * @param imp
+     */
+    public void importNSMapping(NSMapping imp) throws XmpSchemaException {
+        mergeNSMap(imp.nsMaps);
+        mergeComplexBasicTypesDeclarationEntireXMPLevel(imp.complexBasicTypesDeclarationEntireXMPLevel);
+        mergeComplexBasicTypesDeclarationSchemaLevel(imp.complexBasicTypesDeclarationSchemaLevel);
+        mergeComplexBasicTypesDeclarationPropertyLevel(imp.complexBasicTypesDeclarationPropertyLevel);
+    }
+
+    protected void mergeNSMap(Map<String, XMPSchemaFactory> map) throws XmpSchemaException {
+        for (Entry<String, XMPSchemaFactory> entry : map.entrySet() ) {
+            if (this.nsMaps.containsKey(entry.getKey())) {
+                this.nsMaps.get(entry.getKey()).importXMPSchemaFactory(entry.getValue());
+            } else {
+                this.nsMaps.put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    private void mergeComplexBasicTypesDeclarationEntireXMPLevel(Map<String, String> external) {
+        for (Entry<String, String> entry : external.entrySet()) {
+            if(!complexBasicTypesDeclarationEntireXMPLevel.containsKey(entry.getKey())) {
+                complexBasicTypesDeclarationEntireXMPLevel.put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    private void mergeComplexBasicTypesDeclarationSchemaLevel(Map<String, String> external) {
+        for (Entry<String, String> entry : external.entrySet()) {
+            if(!complexBasicTypesDeclarationSchemaLevel.containsKey(entry.getKey())) {
+                complexBasicTypesDeclarationSchemaLevel.put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    private void mergeComplexBasicTypesDeclarationPropertyLevel(Map<String, String> external) {
+        for (Entry<String, String> entry : external.entrySet()) {
+            if(!complexBasicTypesDeclarationPropertyLevel.containsKey(entry.getKey())) {
+                complexBasicTypesDeclarationPropertyLevel.put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    /**
+     * Add a namespace declaration and Schema factory associated
+     * 
+     * @param ns
+     *            the Namespace URI
+     * @param classSchem
+     *            The class representation of the schema linked to the namespace
+     * @throws XmpSchemaException
+     *             When could not read property name in Schema Class given
+     */
+    private void addNameSpace(String ns, Class<? extends XMPSchema> classSchem)
+    throws XmpSchemaException {
+        nsMaps.put(ns, new XMPSchemaFactory(ns, classSchem,	initializePropMapping(ns, classSchem)));
+    }
+
+    /**
+     * Initialize the Property Mapping for a given schema
+     * 
+     * @param ns
+     *            Namespace URI
+     * @param classSchem
+     *            The class representation of the schema linked to the namespace
+     * @return Construct expected properties types representation
+     * @throws XmpSchemaException
+     *             When could not read property name in field with properties
+     *             annotations
+     */
+    private PropMapping initializePropMapping(String ns,
+            Class<? extends XMPSchema> classSchem) throws XmpSchemaException {
+        PropertyType propType;
+        PropertyAttributesAnnotation propAtt;
+        Field[] fields;
+        PropMapping propMap = new PropMapping(ns);
+        fields = classSchem.getFields();
+        String propName = null;
+        for (Field field : fields) {
+            if (field.isAnnotationPresent(PropertyType.class)) {
+                try {
+                    propName = (String) field.get(propName);
+                } catch (Exception e) {
+                    throw new XmpSchemaException(
+                            "couldn't read one type declaration, please check accessibility and declaration of fields annoted in "
+                            + classSchem.getName(), e);
+                }
+                // System.out.println("nameField:"+propName);
+                propType = field.getAnnotation(PropertyType.class);
+                // System.out.println("Type '"+propInfo.propertyType()+"' defined for "+propName);
+                if (!field
+                        .isAnnotationPresent(PropertyAttributesAnnotation.class)) {
+                    propMap.addNewProperty(propName, propType.propertyType(),
+                            null);
+                } else {
+                    // TODO Case where a special annotation is used to specify
+                    // attributes
+                    // NOT IMPLEMENTED YET, JUST TO GIVE A CLUE TO MAKE THIS
+                    propAtt = field
+                    .getAnnotation(PropertyAttributesAnnotation.class);
+                    List<String> attributes = new ArrayList<String>();
+                    for (String att : propAtt.expectedAttributes()) {
+                        attributes.add(att);
+                    }
+                    propMap.addNewProperty(propName, propType.propertyType(),
+                            attributes);
+                }
+            }
+        }
+        return propMap;
+    }
+
+    /**
+     * see if a specific type is known as a basic XMP type
+     * 
+     * @param type
+     *            Type to check
+     * @return True if type is a simple basic type
+     */
+    private boolean isBasicType(String type) {
+        return BASIC_TYPES.contains(type);
+
+    }
+
+    /**
+     * Say if a specific namespace is known
+     * 
+     * @param namespace
+     *            The namespace URI checked
+     * @return True if namespace URI is known
+     */
+    public boolean isContainedNamespace(String namespace) {
+        return nsMaps.containsKey(namespace);
+    }
+
+    /**
+     * Give type of specified property in specified schema (given by its
+     * namespaceURI)
+     * 
+     * @param namespace
+     *            The namespaceURI to explore
+     * @param prop
+     *            the property Qualified Name
+     * @return Property type declared for namespace specified, null if unknown
+     */
+    public String getSpecifiedPropertyType(String namespace, QName prop) {
+        if (nsMaps.containsKey(namespace)) {
+            return nsMaps.get(namespace).getPropertyType(prop.getLocalPart());
+        }
+        // check if its a complexbasicValueType and if it's has been declared
+        return getComplexBasicValueTypeEffectiveType(prop.getPrefix());
+
+    }
+
+    /**
+     * Check if a non basic value type used is describes in the schema which
+     * inlude a property with a such type
+     * 
+     * @param desc
+     *            The schema description associated to the schema which declare
+     *            a property with specific value type
+     * @param definedValueType
+     *            The value type name to find in value types descriptions
+     * @return The description of this specific value type
+     * @throws XmpUnknownValueTypeException
+     *             If no declaration found
+     */
+    private PDFAValueTypeDescription findValueTypeDescription(
+            SchemaDescription desc, String definedValueType)
+    throws XmpUnknownValueTypeException {
+        List<PDFAValueTypeDescription> values = desc.getValueTypes();
+        for (PDFAValueTypeDescription val : values) {
+            if (definedValueType.equals(val.getTypeNameValue())) {
+                return val;
+            }
+        }
+        throw new XmpUnknownValueTypeException("ValueType '" + definedValueType
+                + "' is unknown. no declaration found in this schema");
+    }
+
+    /**
+     * Check if valueType used for a specified property description is known (in
+     * case where it's a normal value type or if a value type which has been
+     * defined in PDF/A Extension schema)
+     * 
+     * @param desc
+     *            The schema description associated to the schema which declare
+     *            a property with specific value type
+     * @param definedValueType
+     *            The value type name to find in value types descriptions
+     * @return value type equivalence (value type which can be treat (orginal
+     *         basic value type or specific value type decomposed to find basic
+     *         types)
+     * @throws XmpUnknownValueTypeException
+     *             When Value Type is unknown
+     * 
+     */
+    private String getValueTypeEquivalence(SchemaDescription desc,
+            String definedValueType) throws XmpUnknownValueTypeException {
+        if (isBasicType(definedValueType)) {
+            return definedValueType;
+        }
+        PDFAValueTypeDescription val = findValueTypeDescription(desc,
+                definedValueType);
+        if (val.getFields().isEmpty()) {
+            // if fields value are note defined we suppose the property is a
+            // Text type
+            return "Text";
+        }
+        return "Field";
+    }
+
+    /**
+     * . For a specific valuetype declared in this schema. This method decompose
+     * it if field are present. and add types expected
+     * 
+     * @param desc
+     *            The schema description associated to the schema which declare
+     *            a property with specific value type
+     * @param valueType
+     *            valueType to analyze
+     * @param prop
+     *            Expected properties types representation
+     * @throws XmpUnknownValueTypeException
+     *             When a Value Type associated is unknown
+     */
+    private void declareAssociatedFieldType(SchemaDescription desc,
+            String valueType, PropMapping prop)
+    throws XmpUnknownValueTypeException {
+
+        PDFAValueTypeDescription val = findValueTypeDescription(desc, valueType);
+        for (PDFAFieldDescription field : val.getFields()) {
+            // TODO case where a field call another nspace property ???
+            String fieldType = getValueTypeEquivalence(desc, field
+                    .getValueTypeValue());
+            if (fieldType.equals("Field")) {
+                throw new XmpUnknownValueTypeException(
+                "ValueType Field reference a valuetype unknown");
+            }
+            prop.addNewProperty(field.getNameValue(), fieldType, null);
+
+        }
+    }
+
+    /**
+     * Add a new namespace Mapping for specific schema declared in PDF/A
+     * Extension schema
+     * 
+     * @param desc
+     *            The schemaDescription associated to the schema
+     * @throws XmpUnknownValueTypeException
+     *             When a Value Type associated is unknown
+     */
+    public void setNamespaceDefinition(SchemaDescription desc)
+    throws XmpUnknownValueTypeException {
+        PropMapping propMap = new PropMapping(desc.getNameSpaceURI());
+        List<PDFAPropertyDescription> props = desc.getProperties();
+        for (int i = 0; i < props.size(); i++) {
+            String type = getValueTypeEquivalence(desc, props.get(i).getValueTypeValue());
+            propMap.addNewProperty(props.get(i).getNameValue(), type, null);
+            if (type.equals("Field")) {
+                declareAssociatedFieldType(desc, props.get(i).getValueTypeValue(), propMap);
+            }
+        }
+        String nsName = desc.getPrefix();
+        String ns = desc.getNameSpaceURI();
+        nsMaps.put(ns, new XMPSchemaFactory(nsName, ns, XMPSchema.class, propMap));
+    }
+
+    /**
+     * Return the specialized schema class representation if it's known (create
+     * and add it to metadata). In other cases, return null
+     * 
+     * @param metadata
+     *            Metadata to link the new schema
+     * @param namespace
+     *            The namespace URI
+     * @return Schema representation
+     * @throws XmpSchemaException
+     *             When Instancing specified Object Schema failed
+     */
+    public XMPSchema getAssociatedSchemaObject(XMPMetadata metadata, String namespace, String prefix) throws XmpSchemaException {
+        if (!nsMaps.containsKey(namespace)) {
+            return null;
+        }
+        XMPSchemaFactory factory = nsMaps.get(namespace);
+        return factory.createXMPSchema(metadata, prefix);
+    }
+
+    /**
+     * Check if a namespace used reference a complex basic types (like
+     * Thumbnails)
+     * 
+     * @param namespace
+     *            The namespace URI to check
+     * @return True if namespace URI is a reference for a complex basic type
+     */
+    public boolean isComplexBasicTypes(String namespace) {
+        return COMPLEX_BASIC_TYPES.containsKey(namespace);
+    }
+
+    /**
+     * Check if a namespace declaration for a complex basic type has been found
+     * and if its valid for the entire XMP stream
+     * 
+     * @param namespace
+     *            the namespace URI
+     * @param prefix
+     *            the prefix associated to this namespace
+     */
+    public void setComplexBasicTypesDeclarationForLevelXMP(String namespace,
+            String prefix) {
+        if (isComplexBasicTypes(namespace)) {
+            complexBasicTypesDeclarationEntireXMPLevel.put(prefix, namespace);
+        }
+    }
+
+    /**
+     * Check if a namespace declaration for a complex basic type has been found
+     * and if its valid for the current schema description (at level of
+     * rdf:Description)
+     * 
+     * @param namespace
+     *            the namespace URI
+     * @param prefix
+     *            the prefix associated to this namespace
+     */
+    public void setComplexBasicTypesDeclarationForLevelSchema(String namespace,
+            String prefix) {
+        if (isComplexBasicTypes(namespace)) {
+            complexBasicTypesDeclarationSchemaLevel.put(prefix, namespace);
+        }
+
+    }
+
+    /**
+     * Check if a namespace declaration for a complex basic type has been found
+     * and if its valid for the current property description
+     * 
+     * @param namespace
+     *            the namespace URI
+     * @param prefix
+     *            the prefix associated to this namespace
+     */
+    public void setComplexBasicTypesDeclarationForLevelProperty(
+            String namespace, String prefix) {
+        if (isComplexBasicTypes(namespace)) {
+            complexBasicTypesDeclarationPropertyLevel.put(prefix, namespace);
+        }
+    }
+
+    /**
+     * Check for all XMP level if a complexBasicValueType prefix has been
+     * declared
+     * 
+     * @param prefix
+     *            The prefix which may design the namespace URI of the complex
+     *            basic type
+     * @return The type if it is known, else null.
+     */
+    public String getComplexBasicValueTypeEffectiveType(String prefix) {
+        if (complexBasicTypesDeclarationPropertyLevel.containsKey(prefix)) {
+            return COMPLEX_BASIC_TYPES
+            .get(complexBasicTypesDeclarationPropertyLevel.get(prefix));
+        }
+        if (complexBasicTypesDeclarationSchemaLevel.containsKey(prefix)) {
+            return COMPLEX_BASIC_TYPES
+            .get(complexBasicTypesDeclarationSchemaLevel.get(prefix));
+        }
+        if (complexBasicTypesDeclarationEntireXMPLevel.containsKey(prefix)) {
+            return COMPLEX_BASIC_TYPES
+            .get(complexBasicTypesDeclarationEntireXMPLevel.get(prefix));
+        }
+        return null;
+    }
+
+    /**
+     * Reset complex Basic types declaration for property level
+     */
+    public void resetComplexBasicTypesDeclarationInPropertyLevel() {
+        complexBasicTypesDeclarationPropertyLevel.clear();
+    }
+
+    /**
+     * Reset complex Basic types declaration for schema level
+     */
+    public void resetComplexBasicTypesDeclarationInSchemaLevel() {
+        complexBasicTypesDeclarationSchemaLevel.clear();
+    }
+
+    /**
+     * Reset complex Basic types declaration for Entire XMP level
+     */
+    public void resetComplexBasicTypesDeclarationInEntireXMPLevel() {
+        complexBasicTypesDeclarationEntireXMPLevel.clear();
+    }
 
 }

Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java?rev=1211604&r1=1211603&r2=1211604&view=diff
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java (original)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLPropertiesDescriptionManager.java Wed Dec  7 19:14:05 2011
@@ -135,7 +135,6 @@ public class XMLPropertiesDescriptionMan
 			}
 
 		} catch (Exception e) {
-			e.printStackTrace();
 			throw new BuildPDFAExtensionSchemaDescriptionException(
 					"Failed to get correct properties descriptions from specified XML stream",
 					e.getCause());
@@ -153,46 +152,5 @@ public class XMLPropertiesDescriptionMan
 		return propDescs;
 	}
 
-	/**
-	 * Sample of using to write/read information
-	 * 
-	 * @param args
-	 *            Not used
-	 * @throws BuildPDFAExtensionSchemaDescriptionException
-	 *             When errors during building/reading xml file
-	 */
-	public static void main(String[] args)
-			throws BuildPDFAExtensionSchemaDescriptionException {
-		XMLPropertiesDescriptionManager ptMaker = new XMLPropertiesDescriptionManager();
-
-		// add Descriptions
-		for (int i = 0; i < 3; i++) {
-			ptMaker.addPropertyDescription("name" + i, "description" + i);
-
-		}
-
-		// Display XML conversion
-		System.out.println("Display XML Result:");
-		ptMaker.toXML(System.out);
-
-		// Sample to show how to build object from XML file
-		ByteArrayOutputStream bos = new ByteArrayOutputStream();
-		ptMaker.toXML(bos);
-		IOUtils.closeQuietly(bos);
-
-		// emulate a new reading
-		InputStream is = new ByteArrayInputStream(bos.toByteArray());
-		ptMaker = new XMLPropertiesDescriptionManager();
-		ptMaker.loadListFromXML(is);
-		List<PropertyDescription> result = ptMaker
-				.getPropertiesDescriptionList();
-		System.out.println();
-		System.out.println();
-		System.out.println("Result of XML Loading :");
-		for (PropertyDescription propertyDescription : result) {
-			System.out.println(propertyDescription.getPropertyName() + " :"
-					+ propertyDescription.getDescription());
-		}
-	}
 
 }

Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java?rev=1211604&r1=1211603&r2=1211604&view=diff
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java (original)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLUtil.java Wed Dec  7 19:14:05 2011
@@ -55,353 +55,353 @@ import org.xml.sax.InputSource;
  * @version $Revision: 1.2 $
  */
 public final class XMLUtil {
-	/**
-	 * Utility class, should not be instantiated.
-	 * 
-	 */
-	private XMLUtil() {
-	}
-
-	/**
-	 * This will parse an XML stream and create a DOM document.
-	 * 
-	 * @param is
-	 *            The stream to get the XML from.
-	 * @return The DOM document.
-	 * @throws IOException
-	 *             It there is an error creating the dom.
-	 */
-	public static Document parse(InputStream is) throws IOException {
-		try {
-			DocumentBuilderFactory builderFactory = DocumentBuilderFactory
-					.newInstance();
-			DocumentBuilder builder = builderFactory.newDocumentBuilder();
-			return builder.parse(is);
-		} catch (Exception e) {
-			IOException thrown = new IOException(e.getMessage());
-			throw thrown;
-		}
-	}
-
-	/**
-	 * This will parse an InputSource and create a DOM document.
-	 * 
-	 * @param is
-	 *            The stream to get the XML from.
-	 * @return The DOM document.
-	 * @throws IOException
-	 *             It there is an error creating the dom.
-	 */
-	public static Document parse(InputSource is) throws IOException {
-		try {
-			DocumentBuilderFactory builderFactory = DocumentBuilderFactory
-					.newInstance();
-			DocumentBuilder builder = builderFactory.newDocumentBuilder();
-			return builder.parse(is);
-		} catch (Exception e) {
-			IOException thrown = new IOException(e.getMessage());
-			throw thrown;
-		}
-	}
-
-	/**
-	 * This will parse an XML stream and create a DOM document.
-	 * 
-	 * @param fileName
-	 *            The file to get the XML from.
-	 * @return The DOM document.
-	 * @throws IOException
-	 *             It there is an error creating the dom.
-	 */
-	public static Document parse(String fileName) throws IOException {
-		try {
-			DocumentBuilderFactory builderFactory = DocumentBuilderFactory
-					.newInstance();
-			DocumentBuilder builder = builderFactory.newDocumentBuilder();
-			return builder.parse(fileName);
-		} catch (Exception e) {
-			IOException thrown = new IOException(e.getMessage());
-			throw thrown;
-		}
-	}
-
-	/**
-	 * Create a new blank XML document.
-	 * 
-	 * @return The new blank XML document.
-	 * 
-	 * @throws IOException
-	 *             If there is an error creating the XML document.
-	 */
-	public static Document newDocument() throws IOException {
-		try {
-			DocumentBuilderFactory builderFactory = DocumentBuilderFactory
-					.newInstance();
-			DocumentBuilder builder = builderFactory.newDocumentBuilder();
-			return builder.newDocument();
-		} catch (Exception e) {
-			IOException thrown = new IOException(e.getMessage());
-			throw thrown;
-		}
-	}
-
-	/**
-	 * Get the first instance of an element by name.
-	 * 
-	 * @param parent
-	 *            The parent to get the element from.
-	 * @param elementName
-	 *            The name of the element to look for.
-	 * @return The element or null if it is not found.
-	 */
-	public static Element getElement(Element parent, String elementName) {
-		Element retval = null;
-		NodeList children = parent.getElementsByTagName(elementName);
-		if (children.getLength() > 0) {
-			retval = (Element) children.item(0);
-		}
-		return retval;
-	}
-
-	/**
-	 * Get the integer value of a subnode.
-	 * 
-	 * @param parent
-	 *            The parent element that holds the values.
-	 * @param nodeName
-	 *            The name of the node that holds the integer value.
-	 * 
-	 * @return The integer value of the node.
-	 */
-	public static Integer getIntValue(Element parent, String nodeName) {
-		String intVal = XMLUtil.getStringValue(XMLUtil.getElement(parent,
-				nodeName));
-		Integer retval = null;
-		if (intVal != null) {
-			retval = new Integer(intVal);
-		}
-		return retval;
-	}
-
-	/**
-	 * Set the integer value of an element.
-	 * 
-	 * @param parent
-	 *            The parent element that will hold this subelement.
-	 * @param nodeName
-	 *            The name of the subelement.
-	 * @param intValue
-	 *            The value to set.
-	 */
-	public static void setIntValue(Element parent, String nodeName,
-			Integer intValue) {
-		Element currentValue = getElement(parent, nodeName);
-		if (intValue == null) {
-			if (currentValue != null) {
-				parent.removeChild(currentValue);
-			} // else it doesn't exist so we don't need to remove it.
-		} else {
-			if (currentValue == null) {
-				currentValue = parent.getOwnerDocument()
-						.createElement(nodeName);
-				parent.appendChild(currentValue);
-			}
-			XMLUtil.setStringValue(currentValue, intValue.toString());
-		}
-	}
-
-	/**
-	 * Get the value of a subnode.
-	 * 
-	 * @param parent
-	 *            The parent element that holds the values.
-	 * @param nodeName
-	 *            The name of the node that holds the value.
-	 * 
-	 * @return The value of the sub node.
-	 */
-	public static String getStringValue(Element parent, String nodeName) {
-		return XMLUtil.getStringValue(XMLUtil.getElement(parent, nodeName));
-	}
-
-	/**
-	 * Set the value of an element.
-	 * 
-	 * @param parent
-	 *            The parent element that will hold this subelement.
-	 * @param nodeName
-	 *            The name of the subelement.
-	 * @param nodeValue
-	 *            The value to set.
-	 */
-	public static void setStringValue(Element parent, String nodeName,
-			String nodeValue) {
-		Element currentValue = getElement(parent, nodeName);
-		if (nodeValue == null) {
-			if (currentValue != null) {
-				parent.removeChild(currentValue);
-			} // else it doesn't exist so we don't need to remove it.
-		} else {
-			if (currentValue == null) {
-				currentValue = parent.getOwnerDocument()
-						.createElement(nodeName);
-				parent.appendChild(currentValue);
-			}
-			XMLUtil.setStringValue(currentValue, nodeValue);
-		}
-	}
-
-	/**
-	 * This will get the text value of an element.
-	 * 
-	 * @param node
-	 *            The node to get the text value for.
-	 * @return The text of the node.
-	 */
-	public static String getStringValue(Element node) {
-		String retval = "";
-		NodeList children = node.getChildNodes();
-		for (int i = 0; i < children.getLength(); i++) {
-			Node next = children.item(i);
-			if (next instanceof Text) {
-				retval = next.getNodeValue();
-			}
-		}
-		return retval;
-	}
-
-	/**
-	 * This will set the text value of an element.
-	 * 
-	 * @param node
-	 *            The node to get the text value for.
-	 * @param value
-	 *            The new value to set the node to.
-	 */
-	public static void setStringValue(Element node, String value) {
-		NodeList children = node.getChildNodes();
-		for (int i = 0; i < children.getLength(); i++) {
-			Node next = children.item(i);
-			if (next instanceof Text) {
-				node.removeChild(next);
-			}
-		}
-		node.appendChild(node.getOwnerDocument().createTextNode(value));
-	}
-
-	/**
-	 * Set an XML element document.
-	 * 
-	 * @param parent
-	 *            The parent document to set the value in.
-	 * @param name
-	 *            The name of the XML element to set.
-	 * @param node
-	 *            The node to set or clear.
-	 */
-	public static void setElementableValue(Element parent, String name,
-			Elementable node) {
-		NodeList nodes = parent.getElementsByTagName(name);
-		if (node == null) {
-			for (int i = 0; i < nodes.getLength(); i++) {
-				parent.removeChild(nodes.item(i));
-			}
-		} else {
-			if (nodes.getLength() == 0) {
-				if (parent.hasChildNodes()) {
-					Node firstChild = parent.getChildNodes().item(0);
-					parent.insertBefore(node.getElement(), firstChild);
-				} else {
-					parent.appendChild(node.getElement());
-				}
-			} else {
-				Node oldNode = nodes.item(0);
-				parent.replaceChild(node.getElement(), oldNode);
-			}
-		}
-	}
-
-	/**
-	 * Save the XML document to a file.
-	 * 
-	 * @param doc
-	 *            The XML document to save.
-	 * @param file
-	 *            The file to save the document to.
-	 * @param encoding
-	 *            The encoding to save the file as.
-	 * 
-	 * @throws TransformerException
-	 *             If there is an error while saving the XML.
-	 */
-	public static void save(Document doc, String file, String encoding)
-			throws TransformerException {
-		Transformer transformer = TransformerFactory.newInstance()
-		.newTransformer();
-		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-		transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
-		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
-				"yes");
-		// initialize StreamResult with File object to save to file
-
-		Result result = new StreamResult(new File(file));
-		DOMSource source = new DOMSource(doc);
-		transformer.transform(source, result);
-	}
-
-	/**
-	 * Save the XML document to an output stream.
-	 * 
-	 * @param doc
-	 *            The XML document to save.
-	 * @param outStream
-	 *            The stream to save the document to.
-	 * @param encoding
-	 *            The encoding to save the file as.
-	 * 
-	 * @throws TransformerException
-	 *             If there is an error while saving the XML.
-	 */
-	public static void save(Node doc, OutputStream outStream, String encoding)
-			throws TransformerException {
-		Transformer transformer = TransformerFactory.newInstance()
-		.newTransformer();
-		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-		transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
-		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
-				"yes");
-
-		// initialize StreamResult with File object to save to file
-		Result result = new StreamResult(outStream);
-		DOMSource source = new DOMSource(doc);
-		transformer.transform(source, result);
-	}
-
-	/**
-	 * Convert the document to an array of bytes.
-	 * 
-	 * @param doc
-	 *            The XML document.
-	 * @param encoding
-	 *            The encoding of the output data.
-	 * 
-	 * @return The XML document as an array of bytes.
-	 * 
-	 * @throws TransformerException
-	 *             If there is an error transforming to text.
-	 */
-	public static byte[] asByteArray(Document doc, String encoding)
-			throws TransformerException {
-		Transformer transformer = TransformerFactory.newInstance()
-				.newTransformer();
-		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-		transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
-		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
-
-		StringWriter writer = new StringWriter();
-		Result result = new StreamResult(writer);
-		DOMSource source = new DOMSource(doc);
-		transformer.transform(source, result);
-		return writer.getBuffer().toString().getBytes();
-	}
+    /**
+     * Utility class, should not be instantiated.
+     * 
+     */
+    private XMLUtil() {
+    }
+
+    /**
+     * This will parse an XML stream and create a DOM document.
+     * 
+     * @param is
+     *            The stream to get the XML from.
+     * @return The DOM document.
+     * @throws IOException
+     *             It there is an error creating the dom.
+     */
+    public static Document parse(InputStream is) throws IOException {
+        try {
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+            .newInstance();
+            DocumentBuilder builder = builderFactory.newDocumentBuilder();
+            return builder.parse(is);
+        } catch (Exception e) {
+            IOException thrown = new IOException(e.getMessage());
+            throw thrown;
+        }
+    }
+
+    /**
+     * This will parse an InputSource and create a DOM document.
+     * 
+     * @param is
+     *            The stream to get the XML from.
+     * @return The DOM document.
+     * @throws IOException
+     *             It there is an error creating the dom.
+     */
+    public static Document parse(InputSource is) throws IOException {
+        try {
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+            .newInstance();
+            DocumentBuilder builder = builderFactory.newDocumentBuilder();
+            return builder.parse(is);
+        } catch (Exception e) {
+            IOException thrown = new IOException(e.getMessage());
+            throw thrown;
+        }
+    }
+
+    /**
+     * This will parse an XML stream and create a DOM document.
+     * 
+     * @param fileName
+     *            The file to get the XML from.
+     * @return The DOM document.
+     * @throws IOException
+     *             It there is an error creating the dom.
+     */
+    public static Document parse(String fileName) throws IOException {
+        try {
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+            .newInstance();
+            DocumentBuilder builder = builderFactory.newDocumentBuilder();
+            return builder.parse(fileName);
+        } catch (Exception e) {
+            IOException thrown = new IOException(e.getMessage());
+            throw thrown;
+        }
+    }
+
+    /**
+     * Create a new blank XML document.
+     * 
+     * @return The new blank XML document.
+     * 
+     * @throws IOException
+     *             If there is an error creating the XML document.
+     */
+    public static Document newDocument() throws IOException {
+        try {
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory
+            .newInstance();
+            DocumentBuilder builder = builderFactory.newDocumentBuilder();
+            return builder.newDocument();
+        } catch (Exception e) {
+            IOException thrown = new IOException(e.getMessage());
+            throw thrown;
+        }
+    }
+
+    /**
+     * Get the first instance of an element by name.
+     * 
+     * @param parent
+     *            The parent to get the element from.
+     * @param elementName
+     *            The name of the element to look for.
+     * @return The element or null if it is not found.
+     */
+    public static Element getElement(Element parent, String elementName) {
+        Element retval = null;
+        NodeList children = parent.getElementsByTagName(elementName);
+        if (children.getLength() > 0) {
+            retval = (Element) children.item(0);
+        }
+        return retval;
+    }
+
+    /**
+     * Get the integer value of a subnode.
+     * 
+     * @param parent
+     *            The parent element that holds the values.
+     * @param nodeName
+     *            The name of the node that holds the integer value.
+     * 
+     * @return The integer value of the node.
+     */
+    public static Integer getIntValue(Element parent, String nodeName) {
+        String intVal = XMLUtil.getStringValue(XMLUtil.getElement(parent,
+                nodeName));
+        if (intVal != null) {
+            return Integer.valueOf(intVal);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Set the integer value of an element.
+     * 
+     * @param parent
+     *            The parent element that will hold this subelement.
+     * @param nodeName
+     *            The name of the subelement.
+     * @param intValue
+     *            The value to set.
+     */
+    public static void setIntValue(Element parent, String nodeName,
+            Integer intValue) {
+        Element currentValue = getElement(parent, nodeName);
+        if (intValue == null) {
+            if (currentValue != null) {
+                parent.removeChild(currentValue);
+            } // else it doesn't exist so we don't need to remove it.
+        } else {
+            if (currentValue == null) {
+                currentValue = parent.getOwnerDocument()
+                .createElement(nodeName);
+                parent.appendChild(currentValue);
+            }
+            XMLUtil.setStringValue(currentValue, intValue.toString());
+        }
+    }
+
+    /**
+     * Get the value of a subnode.
+     * 
+     * @param parent
+     *            The parent element that holds the values.
+     * @param nodeName
+     *            The name of the node that holds the value.
+     * 
+     * @return The value of the sub node.
+     */
+    public static String getStringValue(Element parent, String nodeName) {
+        return XMLUtil.getStringValue(XMLUtil.getElement(parent, nodeName));
+    }
+
+    /**
+     * Set the value of an element.
+     * 
+     * @param parent
+     *            The parent element that will hold this subelement.
+     * @param nodeName
+     *            The name of the subelement.
+     * @param nodeValue
+     *            The value to set.
+     */
+    public static void setStringValue(Element parent, String nodeName,
+            String nodeValue) {
+        Element currentValue = getElement(parent, nodeName);
+        if (nodeValue == null) {
+            if (currentValue != null) {
+                parent.removeChild(currentValue);
+            } // else it doesn't exist so we don't need to remove it.
+        } else {
+            if (currentValue == null) {
+                currentValue = parent.getOwnerDocument()
+                .createElement(nodeName);
+                parent.appendChild(currentValue);
+            }
+            XMLUtil.setStringValue(currentValue, nodeValue);
+        }
+    }
+
+    /**
+     * This will get the text value of an element.
+     * 
+     * @param node
+     *            The node to get the text value for.
+     * @return The text of the node.
+     */
+    public static String getStringValue(Element node) {
+        String retval = "";
+        NodeList children = node.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node next = children.item(i);
+            if (next instanceof Text) {
+                retval = next.getNodeValue();
+            }
+        }
+        return retval;
+    }
+
+    /**
+     * This will set the text value of an element.
+     * 
+     * @param node
+     *            The node to get the text value for.
+     * @param value
+     *            The new value to set the node to.
+     */
+    public static void setStringValue(Element node, String value) {
+        NodeList children = node.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node next = children.item(i);
+            if (next instanceof Text) {
+                node.removeChild(next);
+            }
+        }
+        node.appendChild(node.getOwnerDocument().createTextNode(value));
+    }
+
+    /**
+     * Set an XML element document.
+     * 
+     * @param parent
+     *            The parent document to set the value in.
+     * @param name
+     *            The name of the XML element to set.
+     * @param node
+     *            The node to set or clear.
+     */
+    public static void setElementableValue(Element parent, String name,
+            Elementable node) {
+        NodeList nodes = parent.getElementsByTagName(name);
+        if (node == null) {
+            for (int i = 0; i < nodes.getLength(); i++) {
+                parent.removeChild(nodes.item(i));
+            }
+        } else {
+            if (nodes.getLength() == 0) {
+                if (parent.hasChildNodes()) {
+                    Node firstChild = parent.getChildNodes().item(0);
+                    parent.insertBefore(node.getElement(), firstChild);
+                } else {
+                    parent.appendChild(node.getElement());
+                }
+            } else {
+                Node oldNode = nodes.item(0);
+                parent.replaceChild(node.getElement(), oldNode);
+            }
+        }
+    }
+
+    /**
+     * Save the XML document to a file.
+     * 
+     * @param doc
+     *            The XML document to save.
+     * @param file
+     *            The file to save the document to.
+     * @param encoding
+     *            The encoding to save the file as.
+     * 
+     * @throws TransformerException
+     *             If there is an error while saving the XML.
+     */
+    public static void save(Document doc, String file, String encoding)
+    throws TransformerException {
+        Transformer transformer = TransformerFactory.newInstance()
+        .newTransformer();
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
+        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
+        "yes");
+        // initialize StreamResult with File object to save to file
+
+        Result result = new StreamResult(new File(file));
+        DOMSource source = new DOMSource(doc);
+        transformer.transform(source, result);
+    }
+
+    /**
+     * Save the XML document to an output stream.
+     * 
+     * @param doc
+     *            The XML document to save.
+     * @param outStream
+     *            The stream to save the document to.
+     * @param encoding
+     *            The encoding to save the file as.
+     * 
+     * @throws TransformerException
+     *             If there is an error while saving the XML.
+     */
+    public static void save(Node doc, OutputStream outStream, String encoding)
+    throws TransformerException {
+        Transformer transformer = TransformerFactory.newInstance()
+        .newTransformer();
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
+        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
+        "yes");
+
+        // initialize StreamResult with File object to save to file
+        Result result = new StreamResult(outStream);
+        DOMSource source = new DOMSource(doc);
+        transformer.transform(source, result);
+    }
+
+    /**
+     * Convert the document to an array of bytes.
+     * 
+     * @param doc
+     *            The XML document.
+     * @param encoding
+     *            The encoding of the output data.
+     * 
+     * @return The XML document as an array of bytes.
+     * 
+     * @throws TransformerException
+     *             If there is an error transforming to text.
+     */
+    public static byte[] asByteArray(Document doc, String encoding)
+    throws TransformerException {
+        Transformer transformer = TransformerFactory.newInstance()
+        .newTransformer();
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
+        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+
+        StringWriter writer = new StringWriter();
+        Result result = new StreamResult(writer);
+        DOMSource source = new DOMSource(doc);
+        transformer.transform(source, result);
+        return writer.getBuffer().toString().getBytes();
+    }
 }

Modified: pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java?rev=1211604&r1=1211603&r2=1211604&view=diff
==============================================================================
--- pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java (original)
+++ pdfbox/trunk/xmpbox/src/main/java/org/apache/padaf/xmpbox/parser/XMLValueTypeDescriptionManager.java Wed Dec  7 19:14:05 2011
@@ -170,7 +170,6 @@ public class XMLValueTypeDescriptionMana
 			}
 
 		} catch (Exception e) {
-			e.printStackTrace();
 			throw new BuildPDFAExtensionSchemaDescriptionException(
 					"Failed to get correct valuetypes descriptions from specified XML stream",
 					e.getCause());
@@ -179,66 +178,5 @@ public class XMLValueTypeDescriptionMana
 		}
 	}
 
-	/**
-	 * Sample of using to write/read information
-	 * 
-	 * @param args
-	 *            not used
-	 * @throws BuildPDFAExtensionSchemaDescriptionException
-	 *             When errors during building/reading xml file
-	 */
-	public static void main(String[] args)
-			throws BuildPDFAExtensionSchemaDescriptionException {
-		XMLValueTypeDescriptionManager vtMaker = new XMLValueTypeDescriptionManager();
-
-		// add Descriptions
-		for (int i = 0; i < 3; i++) {
-			vtMaker.addValueTypeDescription("testType" + i, "nsURI" + i,
-					"prefix" + i, "description" + i);
-
-		}
-		List<FieldDescription> fieldSample = new ArrayList<FieldDescription>();
-		for (int i = 0; i < 2; i++) {
-			fieldSample.add(new FieldDescription("fieldName" + i, "valueType"
-					+ i, "description" + i));
-		}
-		vtMaker.addValueTypeDescription("testTypeField",
-				"http://test.withfield.com/vt/", "prefTest",
-				" value type description", fieldSample);
-
-		// Display XML conversion
-		System.out.println("Display XML Result:");
-		vtMaker.toXML(System.out);
-
-		// Sample to show how to build object from XML file
-		ByteArrayOutputStream bos = new ByteArrayOutputStream();
-		vtMaker.toXML(bos);
-		IOUtils.closeQuietly(bos);
-
-		// emulate a new reading
-		InputStream is = new ByteArrayInputStream(bos.toByteArray());
-		vtMaker = new XMLValueTypeDescriptionManager();
-		vtMaker.loadListFromXML(is);
-		List<ValueTypeDescription> result = vtMaker
-				.getValueTypesDescriptionList();
-		System.out.println();
-		System.out.println();
-		System.out.println("Result of XML Loading :");
-		for (ValueTypeDescription propertyDescription : result) {
-			System.out.println(propertyDescription.getType() + " :"
-					+ propertyDescription.getDescription());
-			if (propertyDescription.getFields() != null) {
-				Iterator<FieldDescription> fit = propertyDescription
-						.getFields().iterator();
-				FieldDescription field;
-				while (fit.hasNext()) {
-					field = fit.next();
-					System.out.println("Field " + field.getName() + " :"
-							+ field.getValueType());
-				}
-			}
-		}
-
-	}
 
 }