gt:     this.tarDir ("", dir, tos);
context: /*
  
  Copyright 2010, Google Inc.
  All rights reserved.
  
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:
  
   * Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the following disclaimer
  in the documentation and/or other materials provided with the
  distribution.
   * Neither the name of Google Inc. nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,           
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY           
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   */
  
  package com.google.refine.io;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.FileReader;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.Properties;
  import java.util.zip.GZIPInputStream;
  
  import javax.annotation.PreDestroy;
  import javax.inject.Inject;
  
  import lombok.extern.log4j.Log4j;
  
  import org.apache.tools.tar.TarEntry;
  import org.apache.tools.tar.TarInputStream;
  import org.apache.tools.tar.TarOutputStream;
  import org.json.JSONArray;
  import org.json.JSONException;
  import org.json.JSONObject;
  import org.json.JSONTokener;
  import org.json.JSONWriter;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  
  import com.google.common.io.Files;
  import com.google.refine.ProjectManager;
  import com.google.refine.ProjectManagerFactory;
  import com.google.refine.ProjectMetadata;
  import com.google.refine.SessionWorkspaceDir;
  import com.google.refine.browsing.Engine;
  import com.google.refine.browsing.FilteredRows;
  import com.google.refine.browsing.RowVisitor;
  import com.google.refine.history.HistoryEntryManager;
  import com.google.refine.model.Column;
  import com.google.refine.model.Project;
  import com.google.refine.model.Row;
  import com.google.refine.operations.row.ImportPresetsRowRemovalOperation;
  import com.google.refine.preference.TopList;
  import com.google.refine.process.Process;
  
  import edu.dfci.cccb.mev.dataset.domain.contract.Dataset;
  import edu.dfci.cccb.mev.dataset.domain.contract.Dimension;
  import edu.dfci.cccb.mev.presets.contract.Presets;
  
  @Log4j
  public class FileProjectManager extends ProjectManager {
    final static public String REQUEST_ATTEIBUTE_DATASET = "dataset";
    final static public String REQUEST_ATTEIBUTE_DIMENSION = "dimension";
    final static public String REQUEST_ATTEIBUTE_SELECTIONNAME = "selectionName";
    final static protected String PROJECT_DIR_SUFFIX = ".project";
    final static Logger logger = LoggerFactory.getLogger ("FileProjectManager");
  
    static public synchronized void initialize (File dir) {
      if (getSingleton () != null) {
        logger.warn ("Overwriting singleton already set: " + getSingleton ());
      }
      logger.info ("Using workspace directory: {}", dir.getAbsolutePath ());
      // singleton = new FileProjectManager(dir);
      // This needs our singleton set, thus the unconventional control flow
      ((FileProjectManager) getSingleton ()).recover ();
    }
  
    public FileProjectManager (ProjectManagerFactory pmf) {
      projectManagerFactory = pmf;
    }
  
    public FileProjectManager () {}
  
    private SessionWorkspaceDir _workspaceDir;
  
    public void setWorkspaceDir (SessionWorkspaceDir workspace) {
      // logger.warn("*********************workspace: {} ****************",
      // workspace.toString());
      // logger.info("**************************Set workspace directory: {}",
      // workspace.getAbsolutePath());
      _workspaceDir = workspace;
    }
  
    public SessionWorkspaceDir getWorkspaceDir () {    
      log.info ("Get workspace directory: " + _workspaceDir.getAbsolutePath ());
      return _workspaceDir;
    }
  
      
    @Autowired(required=false) private Dataset dataset;
    public Dataset getRequestHeatmap () {
      return dataset;
    }
    public void setRequestHeatmap (Dataset requestHeatmap) {
      this.dataset = requestHeatmap;
    }
    @Inject Presets presets;
      
    @Override
    public Map<Long, ProjectMetadata> getAllProjectMetadata () {
      Map<Long, ProjectMetadata> heatmapMetadata = new HashMap<Long, ProjectMetadata> ();
      for (Entry<Long, ProjectMetadata> entry : _projectsMetadata.entrySet ()) {
        if (dataset!=null && entry.getValue ().getName ().startsWith (dataset.name ())) {
          heatmapMetadata.put (entry.getKey (), entry.getValue ());
        }else{
          /*if(presets!=null && presets.list ().contains (entry.getValue().getName())==false){
            heatmapMetadata.put (entry.getKey (), entry.getValue ());
          }*/
        }
  
      }
      return heatmapMetadata;
    }
  
    /*protected FileProjectManager(File dir) { super(); _workspaceDir = dir; if
     * (!_workspaceDir.exists() && !_workspaceDir.mkdirs()) {
     * logger.error("Failed to create directory : " + _workspaceDir); return; }
     * load(); } */
  
    static private File getProjectDir (File workspaceDir, long projectID) {
      File dir = new File (workspaceDir, projectID + PROJECT_DIR_SUFFIX);
      if (!dir.exists ()) {
        dir.mkdir ();
      }
      return dir;
    }
  
    public File getProjectDir (long projectID) {
      return getProjectDir (this.getWorkspaceDir (), projectID);
    }
  
    /**
     * Import an external project that has been received as a .tar file, expanded,
     * and copied into our workspace directory.
     * 
     * @param projectID
     */
    @Override
    public boolean loadProjectMetadata (long projectID) {
      synchronized (this) {
        ProjectMetadata metadata = ProjectMetadataUtilities.load (getProjectDir (projectID));
        if (metadata == null) {
          metadata = ProjectMetadataUtilities.recover (getProjectDir (projectID), projectID);
        }
        if (metadata != null) {
          _projectsMetadata.put (projectID, metadata);
          return true;
        } else {
          return false;
        }
      }
    }
  
    @Override
    public void importProject (long projectID, InputStream inputStream, boolean gziped) throws IOException {
      File destDir = this.getProjectDir (projectID);
      destDir.mkdirs ();
  
      if (gziped) {
        GZIPInputStream gis = new GZIPInputStream (inputStream);
        untar (destDir, gis);
      } else {
        untar (destDir, inputStream);
      }
    }
    
    public void copyProject (long sourceProjectId, long destProjectId, String sourceHeatmapId, Dataset destHeatmap, Dimension dimension) throws IOException {
      String destHeatmapId = destHeatmap.name ();
      
      File sourceDir = this.getProjectDir (sourceProjectId);
      log.debug ("copyProject:sourceDir:"+sourceDir.getAbsolutePath ());
      File destDir = this.getProjectDir (destProjectId);
      log.debug ("copyProject:destDir:"+destDir.getAbsolutePath ());
      destDir.mkdirs ();
      
      
      File sourceData = new File (sourceDir, "data.zip");
      File destData = new File (destDir, "data.zip");    
      Files.copy (sourceData,  destData);
      
      File sourceMetadata = new File (sourceDir, "metadata.json");
      File destMetadata = new File (destDir, "metadata.json");    
      Files.copy (sourceMetadata,  destMetadata );
      
      ProjectMetadata sourcepm = getProjectMetadata(sourceProjectId);
      loadProjectMetadata(destProjectId);
      ProjectMetadata destpm = getProjectMetadata(destProjectId);
      if (sourcepm != null && destpm != null ) {
        String destName = sourcepm.getName ().replace (sourceHeatmapId, destHeatmapId);
        destpm.setName (destName);
      }
      
      
      final List<String> listHeader = dimension.keys ();
      final Map<String, String> mapHeader = new HashMap<String, String>(listHeader.size ());
      for(String columnName : listHeader)
        if(!columnName.trim ().equals ("")) mapHeader.put(columnName, null);
          
      Project project = getProject (destProjectId);
      
  //    final Engine engine = getEngine (request, project);
      Engine engine = new Engine(project);
      final List<Integer> unmatchedRowIndices = new ArrayList <Integer>();
      
      RowVisitor visitor = new RowVisitor () {
        Column theIdColumn;
        @Override
        public void start (Project project) {
          theIdColumn = project.columnModel.columns.get (0);
        }
        @Override
        public boolean visit (Project project, int rowIndex, Row row) {
          String cellData = row.getCell (theIdColumn.getCellIndex ()).value.toString ();
          if (mapHeader.containsKey (cellData)) {
  //            if(logger.isDebugEnabled ())
  //              logger.debug ("++ will import"+cellData);
          }else{
            unmatchedRowIndices.add(rowIndex);
  //            if(logger.isDebugEnabled ())
  //              logger.debug ("-- skip import"+rowIndex);
          }
          return false;
        }
  
        @Override
        public void end (Project project) {                        
          try {
            ImportPresetsRowRemovalOperation op = new ImportPresetsRowRemovalOperation(new JSONObject ("{\"facets\":[],\"mode\":\"row-based\"}"), unmatchedRowIndices);
            Process process = op.createProcess(project, new Properties());            
            project.processManager.queueProcess(process);         
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
  
        @Override
        public boolean pass (Project project, int rowIndex, Row row) {                    
          return false;
        }
      };
      
      FilteredRows filteredRows = engine.getAllFilteredRows ();
      filteredRows.accept (project, visitor);
      
    }
   
    
    protected void untar (File destDir, InputStream inputStream) throws IOException {
      TarInputStream tin = new TarInputStream (inputStream);
      TarEntry tarEntry = null;
  
      while ((tarEntry = tin.getNextEntry ()) != null) {
        File destEntry = new File (destDir, tarEntry.getName ());
        File parent = destEntry.getParentFile ();
  
        if (!parent.exists ()) {
          parent.mkdirs ();
        }
  
        if (tarEntry.isDirectory ()) {
          destEntry.mkdirs ();
        } else {
          FileOutputStream fout = new FileOutputStream (destEntry);
          try {
            tin.copyEntryContents (fout);
          } finally {
            fout.close ();
          }
        }
      }
  
      tin.close ();
    }
  
    @Override
    public void exportProject (long projectId, TarOutputStream tos) throws IOException {
      File dir = this.getProjectDir (projectId);
  