/**
   * Create the xml file for the set of collections.
   *
   * @param xmlFile - file to write the xml to
   * @param contributor types - set of contributor types to export
   * @throws IOException - if writing to the file fails.
   */
  public void createXmlFile(File xmlFile, Collection<ContributorType> contributorTypes)
      throws IOException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder;

    String path = FilenameUtils.getPath(xmlFile.getCanonicalPath());
    if (!path.equals("")) {
      File pathOnly = new File(FilenameUtils.getFullPath(xmlFile.getCanonicalPath()));
      FileUtils.forceMkdir(pathOnly);
    }

    if (!xmlFile.exists()) {
      if (!xmlFile.createNewFile()) {
        throw new IllegalStateException("could not create file");
      }
    }

    try {
      builder = factory.newDocumentBuilder();
    } catch (ParserConfigurationException e) {
      throw new IllegalStateException(e);
    }

    DOMImplementation impl = builder.getDOMImplementation();
    DOMImplementationLS domLs = (DOMImplementationLS) impl.getFeature("LS", "3.0");
    LSSerializer serializer = domLs.createLSSerializer();
    LSOutput lsOut = domLs.createLSOutput();

    Document doc = impl.createDocument(null, "contributor_types", null);
    Element root = doc.getDocumentElement();

    FileOutputStream fos;
    OutputStreamWriter outputStreamWriter;
    BufferedWriter writer;

    try {
      fos = new FileOutputStream(xmlFile);

      try {
        outputStreamWriter = new OutputStreamWriter(fos, "UTF-8");
      } catch (UnsupportedEncodingException e) {
        throw new IllegalStateException(e);
      }
      writer = new BufferedWriter(outputStreamWriter);
      lsOut.setCharacterStream(writer);
    } catch (FileNotFoundException e) {
      throw new IllegalStateException(e);
    }

    // create XML for the child collections
    for (ContributorType ct : contributorTypes) {
      Element contributorType = doc.createElement("contributor_type");

      this.addIdElement(contributorType, ct.getId().toString(), doc);
      this.addNameElement(contributorType, ct.getName(), doc);
      this.addDescription(contributorType, ct.getDescription(), doc);
      this.addSystemCode(contributorType, ct.getUniqueSystemCode(), doc);
    }
    serializer.write(root, lsOut);

    try {
      fos.close();
      writer.close();
      outputStreamWriter.close();
    } catch (Exception e) {
      throw new IllegalStateException(e);
    }
  }
  /** Bulk entry creation */
  @Test
  public void createEntriesForUsersMultipleClassTypesTest() throws ClassNotFoundException {
    TransactionStatus ts = tm.getTransaction(td);
    LanguageType lt = new LanguageType();
    lt.setName("languageName");
    languageTypeDAO.makePersistent(lt);

    ContributorType ct = new ContributorType("type");
    contributorTypeDAO.makePersistent(ct);

    IrClassType languageClassType = new IrClassType(LanguageType.class);
    irClassTypeDAO.makePersistent(languageClassType);

    IrClassType contributorClassType = new IrClassType(ContributorType.class);
    irClassTypeDAO.makePersistent(contributorClassType);

    IrAcl irAcl = new IrAcl(lt, languageClassType);
    IrAcl irAcl2 = new IrAcl(ct, contributorClassType);

    irAclDAO.makePersistent(irAcl);
    irAclDAO.makePersistent(irAcl2);

    UserEmail userEmail = new UserEmail("user@email");

    UserManager userManager = new UserManager();
    IrUser user = userManager.createUser("passowrd", "userName");
    user.setLastName("familyName");
    user.setFirstName("forename");
    user.addUserEmail(userEmail, true);

    // save the user
    userDAO.makePersistent(user);

    UserEmail userEmail2 = new UserEmail("user@email2");
    IrUser user2 = userManager.createUser("passowrd2", "userName2");
    user.setLastName("familyName2");
    user.setFirstName("forename2");
    user.addUserEmail(userEmail2, true);
    userDAO.makePersistent(user2);

    // create some permissions
    IrClassTypePermission classTypePermission = new IrClassTypePermission(languageClassType);
    classTypePermission.setName("permissionName");
    classTypePermission.setDescription("permissionDescription");

    IrClassTypePermission classTypePermission1 = new IrClassTypePermission(contributorClassType);
    classTypePermission1.setName("permissionName1");
    classTypePermission1.setDescription("permissionDescription1");

    // save the class type permission
    classTypePermissionDAO.makePersistent(classTypePermission);
    classTypePermissionDAO.makePersistent(classTypePermission1);

    // complete the transaction
    tm.commit(ts);

    // start a new transaction
    ts = tm.getTransaction(td);
    List<IrUser> users = new LinkedList<IrUser>();
    users.add(user);
    users.add(user2);

    List<IrAcl> acls = new LinkedList<IrAcl>();
    acls.add(irAcl);
    acls.add(irAcl2);

    // create user entries for all given acls
    int count = uaceDAO.createUserControlEntriesForUsers(users, acls);
    assert count == 4 : "Should have 4 entries but have " + count;

    List<IrUserAccessControlEntry> entries = new LinkedList<IrUserAccessControlEntry>();

    entries.addAll(uaceDAO.getUserControlEntriesForUsers(irAcl, users));
    entries.addAll(uaceDAO.getUserControlEntriesForUsers(irAcl2, users));

    assert entries.size() == 4 : "Should find 4 entries but found " + entries.size();

    // create permissions for all given user control entries
    List<IrClassTypePermission> permissions = new LinkedList<IrClassTypePermission>();
    permissions.add(classTypePermission);
    permissions.add(classTypePermission1);

    int permissionEntriesCount =
        uaceDAO.createPermissionsForUserControlEntries(entries, permissions);
    assert permissionEntriesCount == 4 : "Should have 4 entries but have " + permissionEntriesCount;

    // commit the transaction
    tm.commit(ts);

    // start a new transaction
    ts = tm.getTransaction(td);
    // clean up the database
    irAclDAO.makeTransient(irAclDAO.getById(irAcl.getId(), false));
    irAclDAO.makeTransient(irAclDAO.getById(irAcl2.getId(), false));
    userDAO.makeTransient(userDAO.getById(user.getId(), false));
    userDAO.makeTransient(userDAO.getById(user2.getId(), false));
    languageTypeDAO.makeTransient(languageTypeDAO.getById(lt.getId(), false));
    contributorTypeDAO.makeTransient(contributorTypeDAO.getById(ct.getId(), false));

    classTypePermissionDAO.makeTransient(
        classTypePermissionDAO.getById(classTypePermission.getId(), false));
    classTypePermissionDAO.makeTransient(
        classTypePermissionDAO.getById(classTypePermission1.getId(), false));

    irClassTypeDAO.makeTransient(irClassTypeDAO.getById(languageClassType.getId(), false));
    irClassTypeDAO.makeTransient(irClassTypeDAO.getById(contributorClassType.getId(), false));

    // commit the transaction
    tm.commit(ts);
  }