Package net.datacrow.core.migration.moduleimport

Source Code of net.datacrow.core.migration.moduleimport.ModuleImporter$Importer

package net.datacrow.core.migration.moduleimport;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.log4j.Logger;

import net.datacrow.core.DataCrow;
import net.datacrow.core.data.DataManager;
import net.datacrow.core.migration.IModuleWizardClient;
import net.datacrow.core.migration.itemimport.ItemImporterHelper;
import net.datacrow.core.modules.DcModule;
import net.datacrow.core.modules.DcModules;
import net.datacrow.core.modules.ModuleJar;
import net.datacrow.core.modules.ModuleJarException;
import net.datacrow.core.modules.xml.XmlField;
import net.datacrow.core.modules.xml.XmlModule;
import net.datacrow.core.objects.DcObject;
import net.datacrow.core.objects.ValidationException;
import net.datacrow.core.resources.DcResources;
import net.datacrow.util.DcImageIcon;
import net.datacrow.util.Utilities;

/**
* This importer is capable of importing a module and its related information.
* The importer takes care of clashes with the module indices. The actual data import
* is managed by the startup process ({@link DcModule#getDefaultData()}).
*
* @author Robert Jan van der Waals
*/
public class ModuleImporter {
   
    private static Logger logger = Logger.getLogger(ModuleImporter.class.getName());

  private File file;
 
  private Importer importer;
 
  public ModuleImporter(File file) {
    this.file = file;
  }
 
  public void start(IModuleWizardClient client) {
      Importer importer = new Importer(client, file);
    importer.start();
  }
 
  public void cancel() {
    if (importer != null)
        importer.cancel();
  }
 
  private class Importer extends Thread {
   
    private boolean canceled = false;
   
    private File file;
    private IModuleWizardClient client;
   
    protected Importer(IModuleWizardClient client, File file) {
      this.client = client;
      this.file = file;
    }
   
    public void cancel() {
      canceled = true;
    }
   
    @Override
    public void run() {
        try {
           
            client.notifyNewTask();
           
            ZipFile zf = new ZipFile(file);
   
                Collection<ModuleJar> modules = new ArrayList<ModuleJar>();
                Map<String, Collection<DcImageIcon>> icons = new HashMap<String, Collection<DcImageIcon>>();
                Map<String, File> data = new HashMap<String, File>();
               
                Enumeration<? extends ZipEntry> list = zf.entries();
               
                client.notifyStarted(zf.size());
                while (list.hasMoreElements() && !canceled) {
                    ZipEntry ze = list.nextElement();
   
                    BufferedInputStream bis = new BufferedInputStream(zf.getInputStream(ze));
                    String name = ze.getName();
                   
                    client.notifyMessage(DcResources.getText("msgProcessingFileX", name));
                   
                    if (name.toLowerCase().endsWith(".xsl")) {
                        // directory name is contained in the name
                        writeToFile(bis, new File(DataCrow.reportDir, name));
                    } else if (name.toLowerCase().endsWith(".jpg")) {
                        String moduleName = name.substring(0, name.indexOf("_"));
                        Collection<DcImageIcon> c = icons.get(moduleName);
                        c = c == null ? new ArrayList<DcImageIcon>() : c;
                       
                        int size = (int) ze.getSize();
                        byte[] bytes = new byte[size];
                        bis.read(bytes);
                       
                        DcImageIcon icon = new DcImageIcon(bytes);
                        icon.setFilename(name.substring(name.indexOf("_") + 1));
                        c.add(icon);
                       
                        icons.put(moduleName, c);
                    } else if (name.toLowerCase().endsWith(".properties")) {
                        writeToFile(bis, new File(DataCrow.moduleDir, name));
                    } else if (name.toLowerCase().endsWith(".xml")) {
                        File file =  new File(System.getProperty("java.io.tmpdir"), name);
                        writeToFile(bis, file);
                        file.deleteOnExit();
                        data.put(name.substring(0, name.toLowerCase().indexOf(".xml")), file);
                    } else if (name.toLowerCase().endsWith(".jar")) {
                        // check if the custom module does not already exist
                        if (DcModules.get(name.substring(0, name.indexOf(".jar"))) == null) {
                            writeToFile(bis, new File(DataCrow.moduleDir, name));
                            ModuleJar moduleJar = new ModuleJar(name);
                            moduleJar.load();
                            modules.add(moduleJar);
                        }
                    }
                    client.notifyProcessed();
                    bis.close();
                }
               
                processData(icons, data);
                reindexModules(modules);

        } catch (Exception e) {
            client.notifyError(e);
        }
       
        client.notifyFinished();
    }
   
    private void reindexModules(Collection<ModuleJar> modules) {
        for (ModuleJar mj : modules) {
            XmlModule xm = mj.getModule();
           
            // module does not exist
            if (DcModules.get(xm.getName()) == null) continue;

              int oldIdx = xm.getIndex();
              int newIdx = DcModules.getAvailableIdx(xm);
             
              xm.setIndex(newIdx);

              // module does already exist and needs to be renumbered
                // all references must also be updated..
              Collection<ModuleJar> others = new ArrayList<ModuleJar>();
              others.addAll(modules);
              for (ModuleJar other : others) {
                  if (other != mj) {
                      XmlModule xmOther = other.getModule();
                     
                      if (xmOther.getParentIndex() == oldIdx)
                          xmOther.setParentIndex(newIdx);
   
                        if (xmOther.getChildIndex() == oldIdx)
                            xmOther.setChildIndex(newIdx);
                     
                      for (XmlField field : xmOther.getFields()) {
                          if (field.getModuleReference() == oldIdx)
                              field.setModuleReference(newIdx);
                      }
                     
                      try {
                          other.save();
                      } catch (ModuleJarException e) {
                          logger.error(e, e);
                      }
                  }
              }
             
              try {
                  // fake registration to make sure the index is known
                  DcModule module = new DcModule(xm);
                  module.setValid(false);
                  DcModules.register(module);
                    mj.save();
                } catch (ModuleJarException e) {
                    logger.error(e, e);
                }
        }
    }
   
    private void processData(Map<String, Collection<DcImageIcon>> icons,
                             Map<String, File> data) {
       
        client.notifyStarted(data.size());
       
        client.notifyMessage(DcResources.getText("msgProcessingModuleItems"));
       
        for (String key : data.keySet()) {
            DcModule module = DcModules.get(key);
           
            client.notifyMessage(DcResources.getText("msgProcessingItemsForX", key));
           
                // for existing module data has to be loaded manually.
                // new modules can use the demo data / default data functionality.
            if (module != null) {
               
                client.notifyMessage(DcResources.getText("msgModuleExistsMergingItems"));
               
                // place the images in the correct folder
                storeImages(key, icons.get(key), true);
                // start the import process
                loadItems(data.get(key), module.getIndex());
               
               
            } else {
                try {
                    client.notifyMessage(DcResources.getText("msgModuleIsNewCreatingItems"));
                    storeImages(key, icons.get(key), false);
                        Utilities.rename(data.get(key), new File(DataCrow.moduleDir + "data", key + ".xml"));
                    } catch (IOException e) {
                        client.notifyError(e);
                    }
            }
            client.notifyProcessed();
        }
    }
   
    private void storeImages(String moduleName, Collection<DcImageIcon> icons, boolean temp) {

        if (icons == null || icons.size() == 0) return;
       
        File dir;
        if (temp) {
              String tempDir = System.getProperty("java.io.tmpdir");
              dir = new File(tempDir, moduleName.toLowerCase() + "_images");
        } else {
            dir = new File(DataCrow.moduleDir + "data", moduleName.toLowerCase() + "_images");
        }
        dir.mkdirs();
       
        client.notifyStartedSubProcess(icons.size());
        client.notifyMessage(DcResources.getText("msgSavingImagesTo", dir.toString()));
       
        for (DcImageIcon icon : icons) {
            try {
                Utilities.writeToFile(icon.getBytes(), new File(dir, icon.getFilename()));
                client.notifyMessage(DcResources.getText("msgSavingImage", icon.getFilename()));
                client.notifySubProcessed();
            } catch (Exception e) {
                client.notifyError(e);
            }
        }
    }
   
    private void loadItems(File file, int moduleIdx) {
        try {
             
            client.notifyMessage("Loading items");
           
            ItemImporterHelper reader = new ItemImporterHelper("XML", moduleIdx, file);
                reader.start();
                Collection<DcObject> items = reader.getItems();
                reader.clear();
               
                client.notifyStartedSubProcess(items.size());
               
               
                int counter = 1;
                for (DcObject item : items) {
                    DcObject other = DataManager.getObjectForString(item.getModule().getIndex(), item.toString());
                    // Check if the item exists and if so, update the item with the found values. Else just create a new item.
                    // This is to make sure the order in which XML files are processed (first software, then categories)
                    // is of no importance (!).
                    try {
                        if (other != null) {
                            client.notifyMessage(DcResources.getText("msgItemExistsMerged", other.toString()));
                            other.setLastInLine(counter == items.size());
                            other.merge(item);
                            other.setChanged(DcObject._SYS_CREATED, false);
                            other.setChanged(DcObject._SYS_MODIFIED, false);
                            other.setValidate(false);
                            other.saveUpdate(true, false);
                        } else {
                            client.notifyMessage(DcResources.getText("msgItemNoExistsCreated", item.toString()));
                            item.setLastInLine(counter == items.size());
                            item.setValidate(false);
                            item.saveNew(true);
                        }
                       
                    } catch (ValidationException ignore) {} // cannot occur (for real!)

                    counter++;
                    client.notifySubProcessed();
                }
        } catch (Exception e) {
            client.notifyError(e);
        }
    }
   
    private void writeToFile(InputStream is, File file) throws IOException{
       
        if (file.getParentFile() != null)
            file.getParentFile().mkdirs();
       
            FileOutputStream fos = new FileOutputStream(file);
           
            int b;
            while ((b = is.read())!= -1)
                fos.write(b);
           
            fos.flush();
            fos.close();
    }
  }
}
TOP

Related Classes of net.datacrow.core.migration.moduleimport.ModuleImporter$Importer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.