Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
rhbz980658 add and use file system persist service
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmason committed Jul 24, 2013
1 parent 14f9d99 commit bea5282
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 8 deletions.
Expand Up @@ -124,7 +124,7 @@ public class ProjectIterationFilesAction implements Serializable
@In
private LocaleDAO localeDAO;

@In("blobPersistService")
@In("fileSystemPersistService")
private FilePersistService filePersistService;

@In
Expand Down Expand Up @@ -326,6 +326,7 @@ private void uploadPotFile()
}

// TODO add logging for disk writing errors
// TODO damason: unify this with Source/TranslationDocumentUpload
private void uploadAdapterFile()
{
String fileName = documentFileUpload.getFileName();
Expand Down
6 changes: 6 additions & 0 deletions zanata-war/src/main/java/org/zanata/dao/DocumentDAO.java
Expand Up @@ -21,6 +21,7 @@
import org.zanata.common.LocaleId;
import org.zanata.common.TransUnitCount;
import org.zanata.common.TransUnitWords;
import org.zanata.file.GlobalDocumentId;
import org.zanata.model.HDocument;
import org.zanata.model.HLocale;
import org.zanata.model.HProjectIteration;
Expand Down Expand Up @@ -325,6 +326,11 @@ public Map<LocaleId, ContainerTranslationStatistics> getStatistics(long docId, L
return returnStats;
}

public HDocument getByGlobalId(GlobalDocumentId id)
{
return getByProjectIterationAndDocId(id.getProjectSlug(), id.getVersionSlug(), id.getDocId());
}

public HDocument getByProjectIterationAndDocId(final String projectSlug, final String iterationSlug, final String docId)
{
// TODO caching might be better with getByDocIdAndIteration(ProjectIterationDAO.getBySlug(), docId)
Expand Down
Expand Up @@ -124,8 +124,7 @@ private InputStream getRawDocumentFromTemporaryBlobTable(String locator)
@Override
public boolean hasPersistedDocument(GlobalDocumentId id)
{
HDocument doc = documentDAO.getByProjectIterationAndDocId(id.getProjectSlug(),
id.getVersionSlug(), id.getDocId());
HDocument doc = documentDAO.getByGlobalId(id);
return doc.getRawDocument() != null;
}
}
Expand Up @@ -27,6 +27,7 @@

public interface FilePersistService
{
// TODO damason: add persistRawDocumentContentFromStream(HRawDocument, InputStream)

public void persistRawDocumentContentFromFile(HRawDocument rawDocument, File rawFile);

Expand Down
150 changes: 150 additions & 0 deletions zanata-war/src/main/java/org/zanata/file/FileSystemPersistService.java
@@ -0,0 +1,150 @@
/*
* Copyright 2013, Red Hat, Inc. and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.zanata.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import lombok.extern.slf4j.Slf4j;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.zanata.ApplicationConfiguration;
import org.zanata.dao.DocumentDAO;
import org.zanata.model.HDocument;
import org.zanata.model.HProject;
import org.zanata.model.HProjectIteration;
import org.zanata.model.HRawDocument;
import org.zanata.rest.service.VirusScanner;

import com.google.common.io.Files;

@Name("fileSystemPersistService")
@Scope(ScopeType.STATELESS)
@AutoCreate
@Slf4j
public class FileSystemPersistService implements FilePersistService
{

private static final String RAW_DOCUMENTS_SUBDIRECTORY = "documents";

@In("applicationConfiguration")
private ApplicationConfiguration appConfig;
@In
private DocumentDAO documentDAO;
@In
private VirusScanner virusScanner;

@Override
public void persistRawDocumentContentFromFile(HRawDocument rawDocument, File fromFile)
{
String fileName = generateFileNameFor(rawDocument);
rawDocument.setContentLocation(fileName);

File newFile = getFileFor(fileName);
try
{
Files.copy(fromFile, newFile);
}
catch (IOException e)
{
// FIXME damason: throw something more specific and handle at call sites
throw new RuntimeException(e);
}

GlobalDocumentId globalId = getGlobalId(rawDocument);
log.info("Persisted raw document {} to file {}", globalId, newFile.getAbsolutePath());
virusScanner.scan(newFile, globalId.toString());
}

private File getFileFor(String fileName)
{
File docsPath = ensureDocsDirectory();
File newFile = new File(docsPath, fileName);
return newFile;
}

private File ensureDocsDirectory()
{
String basePathStringOrNull = appConfig.getDocumentFileStorageLocation();
if (basePathStringOrNull == null)
{
throw new RuntimeException("Document storage location is not configured in JNDI.");
}
File docsDirectory = new File(basePathStringOrNull, RAW_DOCUMENTS_SUBDIRECTORY);
docsDirectory.mkdirs();
return docsDirectory;
}

private static String generateFileNameFor(HRawDocument rawDocument)
{
// Could change to use id of rawDocument, and throw if rawDocument has no id yet.
String idAsString = rawDocument.getDocument().getId().toString();
String extension = rawDocument.getType().getExtension();
return idAsString + "." + extension;
}

// TODO damason: put this in a more appropriate location
private static GlobalDocumentId getGlobalId(HRawDocument rawDocument)
{
HDocument document = rawDocument.getDocument();
HProjectIteration version = document.getProjectIteration();
HProject project = version.getProject();

GlobalDocumentId id = new GlobalDocumentId(
project.getSlug(),
version.getSlug(),
document.getDocId());

return id;
}

@Override
public InputStream getRawDocumentContentAsStream(HRawDocument document) throws RawDocumentContentAccessException
{
File rawFile = getFileFor(document.getContentLocation());
try
{
return new FileInputStream(rawFile);
}
catch (FileNotFoundException e)
{
// FIXME damason: throw more specific exception and handle at call sites
throw new RuntimeException(e);
}
}

@Override
public boolean hasPersistedDocument(GlobalDocumentId id)
{
HDocument doc = documentDAO.getByGlobalId(id);
HRawDocument rawDocument = doc.getRawDocument();
return rawDocument != null
&& getFileFor(rawDocument.getContentLocation()).exists();
}

}
Expand Up @@ -17,4 +17,9 @@ public GlobalDocumentId(String projectSlug, String versionSlug, String docId)
this.docId = docId;
}

@Override
public String toString()
{
return projectSlug + ":" + versionSlug + ":" + docId;
}
}
Expand Up @@ -72,7 +72,7 @@ public class SourceDocumentUpload

@In(create = true, value = "documentUploadUtil")
private DocumentUploadUtil util;
@In("blobPersistService")
@In("fileSystemPersistService")
private FilePersistService filePersistService;
@In
private ZanataIdentity identity;
Expand Down
Expand Up @@ -107,7 +107,7 @@ public class FileService implements FileResource
@In(value = "translationDocumentUploader", create = true)
private TranslationDocumentUpload translationUploader;

@In("blobPersistService")
@In("fileSystemPersistService")
private FilePersistService filePersistService;

@Override
Expand Down
Expand Up @@ -43,7 +43,7 @@ public class GetDocumentListHandler extends AbstractActionHandler<GetDocumentLis
@In
private TranslationFileService translationFileServiceImpl;

@In("blobPersistService")
@In("fileSystemPersistService")
private FilePersistService filePersistService;

@Override
Expand Down
Expand Up @@ -105,7 +105,7 @@ public void beforeTest()
.use("translationFileServiceImpl", translationFileService)
.use("documentServiceImpl", documentService)
.use("documentDAO", documentDAO)
.use("blobPersistService", filePersistService)
.use("fileSystemPersistService", filePersistService)
.allowCycles();

fileService = seam.autowire(FileService.class);
Expand Down
Expand Up @@ -59,7 +59,7 @@ public void setUp() throws Exception
.use("documentDAO", documentDAO)
.use("translationFileServiceImpl", translationFileServiceImpl)
.use("translationStateCacheImpl", translationStateCacheImpl)
.use("blobPersistService", filePersistService)
.use("fileSystemPersistService", filePersistService)
.ignoreNonResolvable()
.autowire(GetDocumentListHandler.class);
// @formatter:on
Expand Down

0 comments on commit bea5282

Please sign in to comment.