public ProjectFile read(POIFSFileSystem fs) throws MPXJException
   {
      try
      {
         ProjectFile projectFile = new ProjectFile();
         ProjectConfig config = projectFile.getProjectConfig();

         config.setAutoTaskID(false);
         config.setAutoTaskUniqueID(false);
         config.setAutoResourceID(false);
         config.setAutoResourceUniqueID(false);
         config.setAutoOutlineLevel(false);
         config.setAutoOutlineNumber(false);
         config.setAutoWBS(false);
         config.setAutoCalendarUniqueID(false);
         config.setAutoAssignmentUniqueID(false);

         projectFile.getEventManager().addProjectListeners(m_projectListeners);

         //
         // Open the file system and retrieve the root directory
         //
         DirectoryEntry root = fs.getRoot();

         //
         // Retrieve the CompObj data, validate the file format and process
         //
         CompObj compObj = new CompObj(new DocumentInputStream((DocumentEntry) root.getEntry("\1CompObj")));
         ProjectProperties projectProperties = projectFile.getProjectProperties();
         projectProperties.setFullApplicationName(compObj.getApplicationName());
         projectProperties.setApplicationVersion(compObj.getApplicationVersion());
         String format = compObj.getFileFormat();
         Class<? extends MPPVariantReader> readerClass = FILE_CLASS_MAP.get(format);
         if (readerClass == null)
         {
            throw new MPXJException(MPXJException.INVALID_FILE + ": " + format);
         }
         MPPVariantReader reader = readerClass.newInstance();
         reader.process(this, projectFile, root);

         //
         // Update the internal structure. We'll take this opportunity to
         // generate outline numbers for the tasks as they don't appear to
         // be present in the MPP file.
         //
         config.setAutoOutlineNumber(true);
         projectFile.updateStructure();
         config.setAutoOutlineNumber(false);

         //
         // Perform post-processing to set the summary flag and clean
         // up any instances where a task has an empty splits list.
         //
         for (Task task : projectFile.getTasks())
         {
            task.setSummary(task.hasChildTasks());
            List<DateRange> splits = task.getSplits();
            if (splits != null && splits.isEmpty())
            {
               task.setSplits(null);
            }
            validationRelations(task);
         }

         //
         // Ensure that the unique ID counters are correct
         //
         config.updateUniqueCounters();

         //
         // Add some analytics
         //
         String projectFilePath = projectFile.getProjectProperties().getProjectFilePath();
         if (projectFilePath != null && projectFilePath.startsWith("<>\\"))
         {
            projectProperties.setFileApplication("Microsoft Project Server");
         }
         else
         {
            projectProperties.setFileApplication("Microsoft");
         }
         projectProperties.setFileType("MPP");

         return (projectFile);
      }

      catch (IOException ex)
      {
         throw new MPXJException(MPXJException.READ_ERROR, ex);
      }

      catch (IllegalAccessException ex)
      {
         throw new MPXJException(MPXJException.READ_ERROR, ex);
      }

      catch (InstantiationException ex)
      {
         throw new MPXJException(MPXJException.READ_ERROR, ex);
      }
   }
public ProjectFile read ( POIFSFileSystem fs ) throws MPXJException { try { ProjectFile projectFile = new ProjectFile ( ) ; ProjectConfig config = projectFile . getProjectConfig ( ) ; config . setAutoTaskID ( false ) ; config . setAutoTaskUniqueID ( false ) ; config . setAutoResourceID ( false ) ; config . setAutoResourceUniqueID ( false ) ; config . setAutoOutlineLevel ( false ) ; config . setAutoOutlineNumber ( false ) ; config . setAutoWBS ( false ) ; config . setAutoCalendarUniqueID ( false ) ; config . setAutoAssignmentUniqueID ( false ) ; projectFile . getEventManager ( ) . addProjectListeners ( m_projectListeners ) ; DirectoryEntry root = fs . getRoot ( ) ; CompObj compObj = new CompObj ( new DocumentInputStream ( ( DocumentEntry ) root . getEntry ( "\1CompObj" ) ) ) ; ProjectProperties projectProperties = projectFile . getProjectProperties ( ) ; projectProperties . setFullApplicationName ( compObj . getApplicationName ( ) ) ; projectProperties . setApplicationVersion ( compObj . getApplicationVersion ( ) ) ; String format = compObj . getFileFormat ( ) ; Class < ? extends MPPVariantReader > readerClass = FILE_CLASS_MAP . get ( format ) ; if ( readerClass == null ) { throw new MPXJException ( MPXJException . INVALID_FILE + ": " + format ) ; } MPPVariantReader reader = readerClass . newInstance ( ) ; reader . process ( this , projectFile , root ) ; config . setAutoOutlineNumber ( true ) ; projectFile . updateStructure ( ) ; config . setAutoOutlineNumber ( false ) ; for ( Task task : projectFile . getTasks ( ) ) { task . setSummary ( task . hasChildTasks ( ) ) ; List < DateRange > splits = task . getSplits ( ) ; if ( splits != null && splits . isEmpty ( ) ) { task . setSplits ( null ) ; } validationRelations ( task ) ; } config . updateUniqueCounters ( ) ; String projectFilePath = projectFile . getProjectProperties ( ) . getProjectFilePath ( ) ; if ( projectFilePath != null && projectFilePath . startsWith ( "<>\\" ) ) { projectProperties . setFileApplication ( "Microsoft Project Server" ) ; } else { projectProperties . setFileApplication ( "Microsoft" ) ; } projectProperties . setFileType ( "MPP" ) ; return ( projectFile ) ; } catch ( IOException ex ) { throw new MPXJException ( MPXJException . READ_ERROR , ex ) ; } catch ( IllegalAccessException ex ) { throw new MPXJException ( MPXJException . READ_ERROR , ex ) ; } catch ( InstantiationException ex ) { throw new MPXJException ( MPXJException . READ_ERROR , ex ) ; } }
Alternative entry point allowing an MPP file to be read from
a user-supplied POI file stream.

@param fs POI file stream
@return ProjectFile instance
@throws MPXJException