/**
   * @param item
   * @param model
   * @throws InvocationTargetException
   * @throws IllegalAccessException
   * @throws NoSuchMethodException
   */
  private void copy(ModelItem item, Model model)
      throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    // Copy ModelItem into Model
    model.setManufacturerModelId(item.getExternalID());
    model.setName(item.getName());
    model.setDescription(item.getDescription());
    model.setFamilyExternalID(item.getFamilyID());

    model.setIsOmaDmEnabled(item.getIsOmaDmEnabled());
    model.setOmaDmVersion(item.getOmaDmVersion());
    model.setIsOmaCpEnabled(item.isOmaCpEnabled());
    model.setOmaCpVersion(item.getOmaCpVersion());
    model.setIsNokiaOtaEnabled(item.isNokiaOtaEnabled());
    model.setNokiaOtaVersion(item.getNokiaOtaVersion());

    model.setSupportedDownloadMethods(item.getSupportedDownloadMethods());
    model.setFirmwareVersionNode(item.getFirmwareVersionNode());
    model.setFirmwareDownloadNode(item.getFirmwareDownloadNode());
    model.setFirmwareUpdateNode(item.getFirmwareUpdateNode());
    model.setFirmwareDownloadAndUpdateNode(item.getFirmwareDownloadAndUpdateNode());
    model.setFirmwareStatusNode(item.getFirmwareStatusNode());
  }
  protected void processCPTemplates() throws SetupException {
    List<String> filenames = this.getFilenames();
    ManagementBeanFactory factory = null;
    try {
      factory = this.getManagementBeanFactory();
      ModelBean modelBean = factory.createModelBean();
      ClientProvTemplateBean cpBean = factory.createClientProvTemplateBean();

      // Import Profile Mappings
      for (String filename : filenames) {
        // Process the file, and import data into database.
        File file = new File(filename);
        if (!file.isAbsolute()) {
          file = new File(this.getSetup().getWorkDir(), filename);
        }

        this.getSetup()
            .getConsole()
            .println("         Loading file [ " + file.getAbsolutePath() + " ]");
        List<ManufacturerItem> items = this.loadManufacturerItems(file.getAbsolutePath());
        for (ManufacturerItem manufacturerItem : items) {
          List<ModelItem> modelItems = manufacturerItem.getModels();
          Manufacturer manufacturer =
              modelBean.getManufacturerByExternalID(manufacturerItem.getExternalID());
          for (ModelItem modelItem : modelItems) {
            // Copy information from family
            this.copyFromFamily(modelItem);

            Model model =
                modelBean.getModelByManufacturerModelID(manufacturer, modelItem.getExternalID());

            if (!modelItem.getCpTemplatesFiles().isEmpty()) {
              this.getSetup()
                  .getConsole()
                  .println(
                      "         * Importing CP Templates for [ "
                          + manufacturer.getExternalId()
                          + " "
                          + model.getManufacturerModelId()
                          + " ]");
            }
            for (String templateFilename : modelItem.getCpTemplatesFiles()) {
              File templateFile = new File(templateFilename);
              if (!templateFile.isAbsolute()) {
                templateFile = new File(this.getSetup().getWorkDir(), templateFilename);
              }
              InputStream in = new FileInputStream(templateFile);
              List<ClientProvTemplate> templates =
                  cpBean.importClientProvTemplates(in, this.getSetup().getWorkDir());
              factory.beginTransaction();
              for (ClientProvTemplate template : templates) {
                cpBean.attach(model, template);
              }
              factory.commit();
              this.getSetup().getConsole().println("           [ " + templateFile + " ] imported!");
            }
          }
        }
      }
    } catch (Exception ex) {
      if (factory != null) {
        factory.rollback();
      }
      throw new SetupException("Error in import models.", ex);
    } finally {
      if (factory != null) {
        factory.release();
      }
    }
  }
  protected void processFirmwares() throws SetupException {
    List<String> filenames = this.getFilenames();
    ManagementBeanFactory factory = null;
    try {
      factory = this.getManagementBeanFactory();
      ModelBean modelBean = factory.createModelBean();

      // Import Profile Mappings
      for (String filename : filenames) {
        // Process the file, and import data into database.
        File file = new File(filename);
        if (!file.isAbsolute()) {
          file = new File(this.getSetup().getWorkDir(), filename);
        }

        this.getSetup()
            .getConsole()
            .println("         Loading file [ " + file.getAbsolutePath() + " ]");
        List<ManufacturerItem> items = this.loadManufacturerItems(file.getAbsolutePath());
        for (ManufacturerItem manufacturerItem : items) {
          List<ModelItem> modelItems = manufacturerItem.getModels();
          Manufacturer manufacturer =
              modelBean.getManufacturerByExternalID(manufacturerItem.getExternalID());
          for (ModelItem modelItem : modelItems) {
            // Copy information from family
            this.copyFromFamily(modelItem);

            Model model =
                modelBean.getModelByManufacturerModelID(manufacturer, modelItem.getExternalID());

            if (!modelItem.getFirmwares().isEmpty()) {
              this.getSetup()
                  .getConsole()
                  .println(
                      "         * Importing Firmwares for [ "
                          + manufacturer.getExternalId()
                          + " "
                          + model.getManufacturerModelId()
                          + " ]");
            }
            for (FirmwareItem firmwareItem : modelItem.getFirmwares()) {
              File firmwareFile = new File(firmwareItem.getFilename());
              if (!firmwareFile.isAbsolute()) {
                firmwareFile = new File(this.getSetup().getWorkDir(), firmwareItem.getFilename());
              }
              if (!firmwareFile.exists()) {
                this.getSetup()
                    .getConsole()
                    .println("Could not load firmware from: " + firmwareFile.getAbsolutePath());
                continue;
              }
              String fromVersion = firmwareItem.getFromVersion();
              String toVersion = firmwareItem.getToVersion();
              this.importFirmware(
                  manufacturer.getExternalId(),
                  model.getManufacturerModelId(),
                  fromVersion,
                  toVersion,
                  firmwareFile.getAbsolutePath());
            }
          }
        }
      }
    } catch (Exception ex) {
      throw new SetupException("Error in import models.", ex);
    } finally {
      if (factory != null) {
        factory.release();
      }
    }
  }
  protected void processModelBasicInformation() throws SetupException {
    List<String> filenames = this.getFilenames();

    ManagementBeanFactory factory = null;
    try {
      factory = this.getManagementBeanFactory();
      ModelBean modelBean = factory.createModelBean();

      if (System.getProperty("otas.dm.home") == null) {
        log.error(
            "ModelTask: "
                + "Could not found 'otas.dm.home' from system properties, please set 'otas.dm.home'.");
      }

      DDFTreeBean ddfBean = factory.createDDFTreeBean();

      // Import Model, DDF, TACs
      for (String filename : filenames) {
        // Process the file, and import data into database.
        File file = new File(filename);
        if (!file.isAbsolute()) {
          file = new File(this.getSetup().getWorkDir(), filename);
        }

        this.getSetup()
            .getConsole()
            .println("         Loading file [ " + file.getAbsolutePath() + " ]");
        List<ManufacturerItem> items = this.loadManufacturerItems(file.getAbsolutePath());
        for (ManufacturerItem manufacturerItem : items) {
          List<ModelItem> modelItems = manufacturerItem.getModels();
          Manufacturer manufacturer =
              modelBean.getManufacturerByExternalID(manufacturerItem.getExternalID());
          for (ModelItem modelItem : modelItems) {
            Model model =
                modelBean.getModelByManufacturerModelID(manufacturer, modelItem.getExternalID());
            if (model == null) {
              log.info(
                  "Create a new model: "
                      + manufacturer.getExternalId()
                      + " "
                      + modelItem.getExternalID());
              model = modelBean.newModelInstance();
              model.setManufacturer(manufacturer);
            } else {
              log.info(
                  "Modify a model: "
                      + manufacturer.getExternalId()
                      + " "
                      + modelItem.getExternalID());
            }

            // Copy information from family
            this.copyFromFamily(modelItem);
            // Copy item into model entity
            this.copy(modelItem, model);

            this.getSetup()
                .getConsole()
                .println(
                    "         * Importing ["
                        + manufacturer.getExternalId()
                        + " "
                        + model.getManufacturerModelId()
                        + "] from [ "
                        + modelItem.getDefinedByFilename()
                        + " ]");
            factory.beginTransaction();
            modelBean.update(model);
            this.getSetup().getConsole().println("           * Basic information processed");

            // ModelSpec: Icon, ...
            String iconFilename = modelItem.getIconFile();
            if (StringUtils.isEmpty(iconFilename)) {
              iconFilename = this.getSetup().getPropertyValue("model.default.icon.file");
            }
            File iconFile = new File(iconFilename);
            if (!iconFile.isAbsolute()) {
              iconFile = new File(this.getSetup().getWorkDir(), iconFilename);
            }
            if (iconFile.exists()) {
              model.setIconBinary(new FileInputStream(iconFile));
            } else {
              this.getSetup()
                  .getConsole()
                  .println("           Could not found icon file: " + iconFile.getAbsolutePath());
            }
            modelBean.update(model);

            Map<String, String> specMap = modelItem.getSpecifications();
            for (String specName : specMap.keySet()) {
              String category = null;
              String name = specName;
              int index = specName.indexOf(".");
              if (index >= 0) {
                category = specName.substring(0, index);
                name = specName.substring(index + 1, specName.length());
              }
              String value = specMap.get(specName);
              List<ModelCharacter> characters =
                  modelBean.findModelCharacters(model, category, name);
              ModelCharacter character = null;
              if (characters != null && characters.size() > 0) {
                // Update exists character
                character = characters.get(0);
              } else {
                // Create a new character
                character = modelBean.newModelCharacterInstance(model, category, name);
              }
              character.setValue(value);
              modelBean.update(character);
            }
            this.getSetup().getConsole().println("           * Specifications processed");

            // TACs
            for (String tac : modelItem.getTacs()) {
              if (StringUtils.isNotEmpty(tac)) {
                modelBean.addTACInfo(model, tac);
                this.getSetup().getConsole().println("           * TAC information processed");
              }
            }

            // DDF Files
            for (String ddfFilename : modelItem.getDdfFiles()) {
              File ddfFile = new File(ddfFilename);
              if (!ddfFile.isAbsolute()) {
                ddfFile = new File(this.getSetup().getWorkDir(), ddfFilename);
              }
              DDFTree ddfTree = null;
              try {
                ddfTree = ddfBean.parseDDFTree(new FileInputStream(ddfFile));
              } catch (Exception e) {
                throw new DMException("Error to parse DDF File: " + ddfFile.getAbsolutePath(), e);
              }
              ddfBean.addDDFTree(ddfTree);
              modelBean.attachDDFTree(model, ddfTree.getID());
              this.getSetup()
                  .getConsole()
                  .println("           * DDF information [ " + ddfFile + " ] processed");
            }
            factory.commit();
          }
        }
      }

    } catch (Exception ex) {
      if (factory != null) {
        factory.rollback();
      }
      throw new SetupException("Error in import models.", ex);
    } finally {
      if (factory != null) {
        factory.release();
      }
    }
  }