1

I wrote java code to extract zip file in alfresco. But through that code some zip files are not getting extracted properly.

And i have one more observation, that if i manually unzip that file and again manually create zip file then its working fine and its successfully getting extracted in alfresco site.

So i am not getting whats the problem exactly.

Is it problem with file or problem with my code or problem with zip file

Can anyone help me with this scenario...

Please refer below Logs for refrence...

2017-01-25 12:10:12,069  ERROR [tandf.ingestion.TransformExceptionService] [org.springframework.jms.listener.DefaultMessageListenerContainer#22-1] Unhandled Exception occured in ingestion pipeline:  org.alfresco.error.AlfrescoRuntimeException: 00250134 Exception in Transaction.
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:542)
    at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:326)
    at com.ixxus.tandf.service.XmlZipExtractService.lambda$extract$4(XmlZipExtractService.java:235)
    at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:548)
    at 

I am Using below code for extracting zip file..

 private void unzipToNode(final String zipFilePath, final NodeRef destinationFolder, final String isbn, final String zipFileNoderef, final String assetType, final NodeRef ingestedNodeRef) throws IOException {

    LOG.debug("Inside : Start :-> unzipToNode, zipFileNoderef : {}", zipFileNoderef);

    String rootDisplayPath = nodeUtils.getDisplayPath(destinationFolder);
    List<NodeRef> folderNodes = new ArrayList<>();

    try (ZipFile zipFile = new ZipFile(zipFilePath); FileInputStream fis = new FileInputStream(zipFilePath); ZipInputStream zipInput = new ZipInputStream(fis);) {

        ZipEntry entry = zipInput.getNextEntry();
        int zipFileSize = zipFile.size();
        LOG.info("{} : zipFileSize from zip api for zipFileNoderef : {}", zipFileSize, zipFileNoderef);
        int zipManualFileCount = 0;

        while (entry != null) {

            zipManualFileCount++;

            LOG.debug("Processing the zip entry : {}, zipFileNoderef : {}", entry.getName(), zipFileNoderef);
            InputStream inputStream = zipFile.getInputStream(entry);

            /** create or get final folder path for current entry */
            NodeRef nodeRef = createOrGetFolderStructure(destinationFolder, entry);
            folderNodes.add(nodeRef);

            String name;

            if (!entry.isDirectory()) {

                name = getFileNameFromEntry(entry);

                /** if zip entry is file, then create and write the new node in validation site */
                createNodeOnValidationSite(nodeRef, name, inputStream, assetType, ingestedNodeRef, rootDisplayPath);
            }

            /** close current entry and fetch next one */
            zipInput.closeEntry();
            entry = zipInput.getNextEntry();
        }

        LOG.info("{} : zipManualFileCount from zip api for zipFileNoderef : {}", zipManualFileCount, zipFileNoderef);

        /** Close the last entry */
        zipInput.closeEntry();
    }

    for(NodeRef folderNode : folderNodes){
        if(nodeUtils.isNodeEmpty(folderNode)){
            LOG.debug("Found empty folder [{}] within .zip [{}]", folderNode, ingestedNodeRef);
            /** if the folder is empty we need to copy all properties to it as well to archive it */
            copyAllProperties(ingestedNodeRef, folderNode, rootDisplayPath, assetType);
        }
    }

    LOG.debug("Inside : End :-> unzipToNode : zipFileNoderef : {}", zipFileNoderef);
}
Deepak Talape
  • 997
  • 1
  • 9
  • 35
  • can you please share your java code that how you are extracting your zip file – Vikash Patel Jan 27 '17 at 06:35
  • @vikash Let me edit the question.... – Deepak Talape Jan 27 '17 at 06:39
  • The problem is most likely with your code extracting the files. It seems that exception is thrown during a rollback ([see here](https://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD/root/projects/repository/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java)), so it's likely not the core issue. – rotarydial Jan 27 '17 at 06:42
  • @DeepakTalape: Thanks for updating your question with the code. I'll take a look at it when I can and post an answer with any insights if a better one isn't there already. :) – rotarydial Jan 27 '17 at 06:45
  • @rotarydial Can you please suggest, what should i do exactly to solve this issue... – Deepak Talape Jan 27 '17 at 06:58

1 Answers1

1

For extract a zip file can you please try this code.

package org.alfresco.repo.action.executer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipException;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.InvalidAspectException;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.InvalidQNameException;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.TempFileProvider;
import org.alfresco.web.bean.repository.Repository;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;

/**
 * Zip action executor
 * 
 * @author Davide Taibi
 */
public class ZipActionExecuter extends ActionExecuterAbstractBase
{
   public static final String NAME = "importzip";
   public static final String PARAM_ENCODING = "encoding";
   public static final String PARAM_DESTINATION_FOLDER = "destination";

   private static final String TEMP_FILE_PREFIX = "alf";
   private static final String TEMP_FILE_SUFFIX = ".zip";

   /**
    * The node service
    */
   private NodeService nodeService;

   /**
    * The content service
    */
   private ContentService contentService;

   private MimetypeService mimetypeService;
   private FileFolderService fileFolderService;

   /**
    * Sets the NodeService to use
    * 
    * @param nodeService The NodeService
    */
   public void setNodeService(NodeService nodeService)
   {
      this.nodeService = nodeService;
   }

   /**
    * Sets the ContentService to use
    * 
    * @param contentService The ContentService
    */
   public void setContentService(ContentService contentService)
   {
      this.contentService = contentService;
   }

   public void setFileFolderService(FileFolderService fileFolderService) {
      this.fileFolderService = fileFolderService;
   }

   public void setMimetypeService(MimetypeService mimetypeService) {
      this.mimetypeService = mimetypeService;
   }

   private void extractFile(ZipFile archive,String mExtractToDir){
      String fileName;
      String destFileName;
      byte[] buffer = new byte[16384];
      mExtractToDir=mExtractToDir+File.separator;
      try {
         for ( Enumeration e = archive.getEntries(); e.hasMoreElements(); )
         {
            ZipEntry entry = (ZipEntry)e.nextElement();
            if ( ! entry.isDirectory() )
            {
               fileName = entry.getName();
               fileName = fileName.replace('/', File.separatorChar);
               destFileName = mExtractToDir + fileName;
               File destFile = new File(destFileName);
               String parent = destFile.getParent();
               if ( parent != null )
               {
                  File parentFile = new File(parent);
                  if ( ! parentFile.exists() )
                     parentFile.mkdirs();
               }
               InputStream in = archive.getInputStream(entry);
               OutputStream out = new FileOutputStream(destFileName);
               int count;
               while ( (count = in.read(buffer)) != -1 )
                  out.write(buffer, 0, count );
               in.close();
               out.close();
            }else{
               File newdir = new File( mExtractToDir + entry.getName() );
               newdir.mkdir();
            }
         }
      } catch (ZipException e) {
         e.printStackTrace();
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }    

   private void deleteDir(File dir){
         File elenco=new File(dir.getPath());
         for (File file:elenco.listFiles()){
            if (file.isFile())
               file.delete();
            else
               deleteDir(file);
         }
         dir.delete();
   }

   public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) {
      String spaceType;
      NodeRef parentNodeRef;
      FileInfo fileInfo;
      NodeRef nodeRef;

      if (this.nodeService.exists(actionedUponNodeRef) == true) {
         ContentReader reader = this.contentService.getReader(
               actionedUponNodeRef, ContentModel.PROP_CONTENT);
         if (reader != null) {
            if (MimetypeMap.MIMETYPE_ZIP.equals(reader.getMimetype())) {
               File zFile = null;
               ZipFile zipFile = null;
               try {
                  spaceType = ContentModel.TYPE_FOLDER.toString();
                  String dirName = ""+this.nodeService.getProperty(actionedUponNodeRef, ContentModel.PROP_NAME);
                  dirName=dirName.substring(0,dirName.indexOf(".zip"));
                  parentNodeRef = (NodeRef)ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER);// this.nodeService.getRootNode(Repository.getStoreRef());
                  fileInfo = fileFolderService.create(
                        parentNodeRef,
                        dirName,
                        Repository.resolveToQName(spaceType));
                  nodeRef = fileInfo.getNodeRef();

                  zFile = TempFileProvider.createTempFile(
                        TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
                  reader.getContent(zFile);
                  zipFile = new ZipFile(zFile, "Cp437");
                  File tempDir=new File(TempFileProvider.getTempDir().getPath()+File.separator+dirName);
                  if (tempDir.exists()) deleteDir(tempDir);
                  extractFile(zipFile,tempDir.getPath());
                  importFile(tempDir.getPath(),nodeRef);
                  deleteDir(tempDir);
               } catch (ContentIOException e) {
                  e.printStackTrace();
               } catch (InvalidNodeRefException e) {
                  e.printStackTrace();
               } catch (FileExistsException e) {
                  e.printStackTrace();
               } catch (IOException e) {
                  e.printStackTrace();
               }
            }
         }
      }
   }

   private void importFile(String dir,NodeRef root){
      File elenco=new File(dir);
      for (File file:elenco.listFiles()){
         try {
            if (file.isFile()){
               InputStream contentStream = new FileInputStream(file);
               // assign name
               String fileName=file.getName();
               Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
               contentProps.put(ContentModel.PROP_NAME, fileName);
               // create content node
               ChildAssociationRef association = nodeService
               .createNode(
                     root,
                     ContentModel.ASSOC_CONTAINS,
                     QName.createQName(
                           NamespaceService.CONTENT_MODEL_PREFIX,
                           fileName),
                           ContentModel.TYPE_CONTENT,
                           contentProps);
               NodeRef content = association.getChildRef();
               // add titled aspect (for Web Client display)
               Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
               titledProps.put(ContentModel.PROP_TITLE, fileName);
               titledProps.put(ContentModel.PROP_DESCRIPTION,fileName);
               nodeService.addAspect(content,
                     ContentModel.ASPECT_TITLED,
                     titledProps);
               ContentWriter writer = contentService.getWriter(content,
                     ContentModel.PROP_CONTENT, true);
               writer.setMimetype(mimetypeService.guessMimetype(file.getAbsolutePath()));
               writer.setEncoding("Cp437");
               writer.putContent(contentStream);          
            }else{
               String spaceType = ContentModel.TYPE_FOLDER.toString();
               FileInfo fileInfo = fileFolderService.create(
                     root,
                     file.getName(),
                     Repository.resolveToQName(spaceType));

               importFile(file.getPath(),fileInfo.getNodeRef());
            }
         } catch (InvalidTypeException e) {
            e.printStackTrace();
         } catch (InvalidAspectException e) {
            e.printStackTrace();
         } catch (InvalidQNameException e) {
            e.printStackTrace();
         } catch (ContentIOException e) {
            e.printStackTrace();
         } catch (FileNotFoundException e) {
            e.printStackTrace();
         } catch (InvalidNodeRefException e) {
            e.printStackTrace();
         } catch (FileExistsException e) {
            e.printStackTrace();
         }
      }
   }

   protected void addParameterDefinitions(List<ParameterDefinition> paramList) 
   {
      paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF, 
            true, getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));
      paramList.add(new ParameterDefinitionImpl(PARAM_ENCODING, DataTypeDefinition.TEXT, 
            true, getParamDisplayLabel(PARAM_ENCODING)));
   }
}

Moreover the file importzip-action-messages.properties :

importzip.title=Import Zip File
importzip.description=This Action import zip file into alfresco
importzip.aspect-name.display-label=The name of the aspect to apply to the node.

and add the following line to …-context.xml, (you can use action-services-context.xml)

<bean id="importzip" class="org.alfresco.repo.action.executer.ZipActionExecuter" parent="action-executer">
        <property name="nodeService">
            <ref bean="NodeService"></ref>
        </property>
        <property name="contentService">
            <ref bean="ContentService" />
        </property>
        <property name="mimetypeService">
            <ref bean="MimetypeService"></ref>
        </property>
                <property name="fileFolderService">
            <ref bean="FileFolderService"></ref>
        </property>
  </bean>
   <bean id="importzip-messages" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
       <property name="resourceBundles">
          <list>
             <value>org.alfresco.repo.action.importzip-action-messages</value>
          </list>
       </property>
      </bean>

and finally add this line to my web-client-config-custom.xml

<config evaluator="string-compare" condition="Action Wizards">
      <action-handlers>
         <handler name="importzip" class="org.alfresco.web.bean.actions.handlers.ImportHandler" />
      </action-handlers>         
</config>
Vikash Patel
  • 1,328
  • 9
  • 28