All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.mpxj.primavera.p3.P3PRXFileReader Maven / Gradle / Ivy

Go to download

Library that provides facilities to allow project information to be manipulated in Java and .Net. Supports a range of data formats: Microsoft Project Exchange (MPX), Microsoft Project (MPP,MPT), Microsoft Project Data Interchange (MSPDI XML), Microsoft Project Database (MPD), Planner (XML), Primavera (PM XML, XER, and database), Asta Powerproject (PP, MDB), Asta Easyplan (PP), Phoenix Project Manager (PPX), FastTrack Schedule (FTS), and the Standard Data Exchange Format (SDEF).

There is a newer version: 13.6.0
Show newest version
/*
 * file:       P3PRXFileReader.java
 * author:     Jon Iles
 * copyright:  (c) Packwood Software 2018
 * date:       11/03/2018
 */

/*
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

package net.sf.mpxj.primavera.p3;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import net.sf.mpxj.MPXJException;
import net.sf.mpxj.ProjectFile;
import net.sf.mpxj.common.FileHelper;
import net.sf.mpxj.common.FixedLengthInputStream;
import net.sf.mpxj.common.InputStreamHelper;
import net.sf.mpxj.primavera.common.Blast;
import net.sf.mpxj.primavera.suretrak.SureTrakDatabaseReader;
import net.sf.mpxj.reader.AbstractProjectStreamReader;

/**
 * Reads a schedule data from a P3 PRX file.
 */
public final class P3PRXFileReader extends AbstractProjectStreamReader
{
   @Override public ProjectFile read(InputStream stream) throws MPXJException
   {
      File tempDir = null;

      try
      {
         InputStreamHelper.skip(stream, 27000);
         tempDir = FileHelper.createTempDir();

         while (stream.available() > 0)
         {
            extractFile(stream, tempDir);
         }

         // Normally we'd expect a PRX file to contains a P3 database...
         if (!P3DatabaseReader.listProjectNames(tempDir).isEmpty())
         {
            return P3DatabaseReader.setProjectNameAndRead(tempDir);
         }

         // But I have found PRX files which contain a SureTrak database
         if (!SureTrakDatabaseReader.listProjectNames(tempDir).isEmpty())
         {
            return SureTrakDatabaseReader.setProjectNameAndRead(tempDir);
         }

         return null;
      }

      catch (IOException ex)
      {
         throw new MPXJException("Failed to parse file", ex);
      }

      finally
      {
         FileHelper.deleteQuietly(tempDir);
      }
   }

   /**
    * Extracts the data for a single file from the input stream and writes
    * it to a target directory.
    *
    * @param stream input stream
    * @param dir target directory
    */
   private void extractFile(InputStream stream, File dir) throws IOException
   {
      InputStreamHelper.skip(stream, 8); // header
      byte[] fileName = InputStreamHelper.read(stream, 13);
      byte[] dataSize = InputStreamHelper.read(stream, 4);

      int dataSizeValue = getInt(dataSize, 0);
      String fileNameValue = getString(fileName, 0);
      File file = new File(dir, fileNameValue);

      if (dataSizeValue == 0)
      {
         FileHelper.createNewFile(file);
      }
      else
      {
         OutputStream os = Files.newOutputStream(file.toPath());
         FixedLengthInputStream inputStream = new FixedLengthInputStream(stream, dataSizeValue);
         Blast blast = new Blast();
         blast.blast(inputStream, os);
         os.close();
      }
   }

   /**
    * Retrieve a four byte integer.
    *
    * @param data byte array
    * @param offset offset into array
    * @return int value
    */
   private int getInt(byte[] data, int offset)
   {
      int result = 0;
      int i = offset;
      for (int shiftBy = 0; shiftBy < 32; shiftBy += 8)
      {
         result |= ((data[i] & 0xff)) << shiftBy;
         ++i;
      }
      return result;
   }

   /**
    * Retrieve a string from the byte array.
    *
    * @param data byte array
    * @param offset offset into byte array
    * @return String instance
    */
   private String getString(byte[] data, int offset)
   {
      StringBuilder buffer = new StringBuilder();
      char c;

      for (int loop = 0; offset + loop < data.length; loop++)
      {
         c = (char) data[offset + loop];

         if (c == 0)
         {
            break;
         }

         buffer.append(c);
      }

      return buffer.toString();
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy