Mercurial > hg > LGDataverses
diff src/main/java/edu/harvard/iq/dataverse/dataaccess/FileAccessObject.java @ 10:a50cf11e5178
Rewrite LGDataverse completely upgrading to dataverse4.0
| author | Zoe Hong <zhong@mpiwg-berlin.mpg.de> |
|---|---|
| date | Tue, 08 Sep 2015 17:00:21 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/edu/harvard/iq/dataverse/dataaccess/FileAccessObject.java Tue Sep 08 17:00:21 2015 +0200 @@ -0,0 +1,306 @@ +/* + Copyright (C) 2005-2012, by the President and Fellows of Harvard College. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Dataverse Network - A web application to share, preserve and analyze research data. + Developed at the Institute for Quantitative Social Science, Harvard University. + Version 3.0. +*/ + +package edu.harvard.iq.dataverse.dataaccess; + +// java core imports: +import java.io.IOException; +import java.io.File; +import java.io.InputStream; +import java.io.FileInputStream; +import java.util.List; +import java.util.Iterator; + + +// DVN App imports: +import edu.harvard.iq.dataverse.DataFile; +//mport edu.harvard.iq.dataverse.TabularDataFile; +import edu.harvard.iq.dataverse.datavariable.DataVariable; +import java.io.FileOutputStream; +import java.nio.channels.Channel; +import java.nio.channels.WritableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class FileAccessObject extends DataAccessObject { + + public FileAccessObject () throws IOException { + this(null); + } + + public FileAccessObject(DataFile file) throws IOException { + this (file, null); + + } + + public FileAccessObject(DataFile file, DataAccessRequest req) throws IOException { + + super(file, req); + + /* + if (file != null && file.isRemote()) { + //return null; + throw new IOException ("not a local file."); + } + */ + + this.setIsLocalFile(true); + this.setIsDownloadSupported(true); + this.setIsNIOSupported(true); + } + + private boolean isReadAccess = false; + private boolean isWriteAccess = false; + + @Override + public boolean canAccess (String location) throws IOException{ + return true; + } + + @Override + public boolean canRead () { + return isReadAccess; + } + + @Override + public boolean canWrite () { + return isWriteAccess; + } + //public void open (String location) throws IOException{ + + //} + + //private void open (DataFile file, Object req) throws IOException { + @Override + public void open () throws IOException { + + DataFile file = this.getFile(); + DataAccessRequest req = this.getRequest(); + + + //if (req instanceof HttpServletRequest) { + // if (((HttpServletRequest)req).getParameter("noVarHeader") != null) { + // this.setNoVarHeader(true); + // } + //} + + if (req.getParameter("noVarHeader") != null) { + this.setNoVarHeader(true); + } + InputStream in = openLocalFileAsStream(file); + + if (in == null) { + throw new IOException ("Failed to open local file "+file.getFileSystemLocation()); + } + + this.setInputStream(in); + + this.setSize(getLocalFileSize(file)); + + this.setMimeType(file.getContentType()); + this.setFileName(file.getFileMetadata().getLabel()); + + + if (file.getContentType() != null && + file.getContentType().equals("text/tab-separated-values") && + file.isTabularData() && + file.getDataTable() != null && + (!this.noVarHeader())) { + + List datavariables = file.getDataTable().getDataVariables(); + String varHeaderLine = generateVariableHeader(datavariables); + this.setVarHeader(varHeaderLine); + } + + // The HTTP headers for the final download (when an HTTP download + // of the file is requested, as opposed to the object being read by + // another part of the system). This is a TODO -- need to design this + // carefully. + +// setDownloadContentHeaders (localDownload); + + + this.setStatus(200); + } // End of initiateLocalDownload; + + @Override + public String getStorageLocation() { + + Path studyDirectoryPath = this.getFile().getOwner().getFileSystemDirectory(); + + if (studyDirectoryPath == null) { + return null; + } + String studyDirectory = studyDirectoryPath.toString(); + + return Paths.get(studyDirectory, this.getFile().getFileSystemName()).toString(); + } + + @Override + public Path getFileSystemPath() throws IOException { + if (this.getFile() == null) { + throw new IOException("No datafile defined in the Data Access Object"); + } + + if (this.getFile().getOwner() == null) { + throw new IOException("Data Access: no parent dataset defined for this datafile"); + } + + Path studyDirectoryPath = this.getFile().getOwner().getFileSystemDirectory(); + + if (studyDirectoryPath == null) { + throw new IOException("Could not determine the filesystem directory of the parent dataset."); + } + String datasetDirectory = studyDirectoryPath.toString(); + + if (this.getFile().getFileSystemName() == null || "".equals(this.getFile().getFileSystemName())) { + throw new IOException("Data Access: No local storage identifier defined for this datafile."); + } + + return Paths.get(datasetDirectory, this.getFile().getFileSystemName()); + + } + + @Override + public void delete() throws IOException { + Path victim = getFileSystemPath(); + + if (victim != null) { + Files.delete(victim); + } else { + throw new IOException("Could not locate physical file location for the Filesystem object."); + } + } + + @Override + public void openChannel (DataAccessOption... options) throws IOException { + + for (DataAccessOption option: options) { + // In the future we may need to be able to open read-write + // Channels; no support, or use case for that as of now. + + if (option == DataAccessOption.READ_ACCESS) { + isReadAccess = true; + continue; + } + + if (option == DataAccessOption.WRITE_ACCESS) { + isWriteAccess = true; + continue; + } + } + + if (!isReadAccess && !isWriteAccess) { + isReadAccess = true; + } + + if (isReadAccess) { + // TODO: + // Make sure all the tasks performed by the old-style, InputStream-based + // method are still taken care of. + openReadableChannel(); + } else if (isWriteAccess) { + openWritableChannel(); + } + + } + + private void openWritableChannel () throws IOException { + DataFile datafile = this.getFile(); + + if (datafile == null) { + throw new IOException ("Data Access: No Datafile defined in the DataAccessObject."); + } + + channel = new FileOutputStream(getFileSystemPath().toFile()).getChannel(); + + } + + private void openReadableChannel () throws IOException { + DataFile datafile = this.getFile(); + + if (datafile == null) { + throw new IOException ("Data Access: No Datafile defined in the DataAccessObject."); + } + + channel = openLocalFileAsStream(datafile).getChannel(); + } + + // Auxilary helper methods, filesystem access-specific: + + public long getLocalFileSize (DataFile file) { + long fileSize = -1; + File testFile = null; + + try { + testFile = file.getFileSystemLocation().toFile(); + if (testFile != null) { + fileSize = testFile.length(); + } + } catch (Exception ex) { + return -1; + } + + return fileSize; + } + + public FileInputStream openLocalFileAsStream (DataFile file) { + FileInputStream in; + + try { + in = new FileInputStream(file.getFileSystemLocation().toFile()); + } catch (Exception ex) { + // We don't particularly care what the reason why we have + // failed to access the file was. + // From the point of view of the download subsystem, it's a + // binary operation -- it's either successfull or not. + // If we can't access it for whatever reason, we are saying + // it's 404 NOT FOUND in our HTTP response. + return null; + } + + return in; + } + + private String generateVariableHeader(List dvs) { + String varHeader = null; + + if (dvs != null) { + Iterator iter = dvs.iterator(); + DataVariable dv; + + if (iter.hasNext()) { + dv = (DataVariable) iter.next(); + varHeader = dv.getName(); + } + + while (iter.hasNext()) { + dv = (DataVariable) iter.next(); + varHeader = varHeader + "\t" + dv.getName(); + } + + varHeader = varHeader + "\n"; + } + + return varHeader; + } + +} \ No newline at end of file
