/**
   * Serialize a single schema (namespace) registry entry
   *
   * @param xmlSerializer XML serializer
   * @param mdSchema DSpace metadata schema
   * @throws SAXException if XML error
   * @throws RegistryExportException if export error
   */
  private static void saveSchema(XMLSerializer xmlSerializer, MetadataSchema mdSchema)
      throws SAXException, RegistryExportException {
    // If we haven't got a schema, it's an error
    if (mdSchema == null) {
      throw new RegistryExportException("no schema to export");
    }

    String name = mdSchema.getName();
    String namespace = mdSchema.getNamespace();

    if (name == null || "".equals(name)) {
      System.out.println("name is null, skipping");
      return;
    }

    if (namespace == null || "".equals(namespace)) {
      System.out.println("namespace is null, skipping");
      return;
    }

    // Output the parent tag
    xmlSerializer.startElement("dc-schema", null);

    // Output the schema name
    xmlSerializer.startElement("name", null);
    xmlSerializer.characters(name.toCharArray(), 0, name.length());
    xmlSerializer.endElement("name");

    // Output the schema namespace
    xmlSerializer.startElement("namespace", null);
    xmlSerializer.characters(namespace.toCharArray(), 0, namespace.length());
    xmlSerializer.endElement("namespace");

    xmlSerializer.endElement("dc-schema");
  }
  /**
   * Serialize a single metadata field registry entry to xml
   *
   * @param context DSpace context
   * @param xmlSerializer xml serializer
   * @param mdField DSpace metadata field
   * @throws SAXException if XML error
   * @throws RegistryExportException if export error
   * @throws SQLException if database error
   * @throws IOException if IO error
   */
  private static void saveType(Context context, XMLSerializer xmlSerializer, MetadataField mdField)
      throws SAXException, RegistryExportException, SQLException, IOException {
    // If we haven't been given a field, it's an error
    if (mdField == null) {
      throw new RegistryExportException("no field to export");
    }

    // Get the data from the metadata field
    String schemaName = getSchemaName(context, mdField);
    String element = mdField.getElement();
    String qualifier = mdField.getQualifier();
    String scopeNote = mdField.getScopeNote();

    // We must have a schema and element
    if (schemaName == null || element == null) {
      throw new RegistryExportException("incomplete field information");
    }

    // Output the parent tag
    xmlSerializer.startElement("dc-type", null);

    // Output the schema name
    xmlSerializer.startElement("schema", null);
    xmlSerializer.characters(schemaName.toCharArray(), 0, schemaName.length());
    xmlSerializer.endElement("schema");

    // Output the element
    xmlSerializer.startElement("element", null);
    xmlSerializer.characters(element.toCharArray(), 0, element.length());
    xmlSerializer.endElement("element");

    // Output the qualifier, if present
    if (qualifier != null) {
      xmlSerializer.startElement("qualifier", null);
      xmlSerializer.characters(qualifier.toCharArray(), 0, qualifier.length());
      xmlSerializer.endElement("qualifier");
    } else {
      xmlSerializer.comment("unqualified");
    }

    // Output the scope note, if present
    if (scopeNote != null) {
      xmlSerializer.startElement("scope_note", null);
      xmlSerializer.characters(scopeNote.toCharArray(), 0, scopeNote.length());
      xmlSerializer.endElement("scope_note");
    } else {
      xmlSerializer.comment("no scope note");
    }

    xmlSerializer.endElement("dc-type");
  }
  /**
   * Save a registry to a filepath
   *
   * @param file filepath
   * @param schema schema definition to save
   * @throws SQLException if database error
   * @throws IOException if IO error
   * @throws SAXException if XML error
   * @throws RegistryExportException if export error
   */
  public static void saveRegistry(String file, String schema)
      throws SQLException, IOException, SAXException, RegistryExportException {
    // create a context
    Context context = new Context();
    context.setIgnoreAuthorization(true);

    OutputFormat xmlFormat = new OutputFormat(Method.XML, "UTF-8", true);
    xmlFormat.setLineWidth(120);
    xmlFormat.setIndent(4);

    XMLSerializer xmlSerializer =
        new XMLSerializer(new BufferedWriter(new FileWriter(file)), xmlFormat);
    //        XMLSerializer xmlSerializer = new XMLSerializer(System.out, xmlFormat);
    xmlSerializer.startDocument();
    xmlSerializer.startElement("dspace-dc-types", null);

    // Save the schema definition(s)
    saveSchema(context, xmlSerializer, schema);

    List<MetadataField> mdFields = null;

    // If a single schema has been specified
    if (schema != null && !"".equals(schema)) {
      // Get the id of that schema
      MetadataSchema mdSchema = metadataSchemaService.find(context, schema);
      if (mdSchema == null) {
        throw new RegistryExportException("no schema to export");
      }

      // Get the metadata fields only for the specified schema
      mdFields = metadataFieldService.findAllInSchema(context, mdSchema);
    } else {
      // Get the metadata fields for all the schemas
      mdFields = metadataFieldService.findAll(context);
    }

    // Output the metadata fields
    for (MetadataField mdField : mdFields) {
      saveType(context, xmlSerializer, mdField);
    }

    xmlSerializer.endElement("dspace-dc-types");
    xmlSerializer.endDocument();

    // abort the context, as we shouldn't have changed it!!
    context.abort();
  }