Package org.olat.fileresource

Source Code of org.olat.fileresource.FileResourceManager

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/

package org.olat.fileresource;

import java.io.File;
import java.util.Locale;

import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.media.MediaResource;
import org.olat.core.gui.translator.Translator;
import org.olat.core.id.OLATResourceable;
import org.olat.core.logging.AssertException;
import org.olat.core.logging.OLATRuntimeException;
import org.olat.core.util.FileUtils;
import org.olat.core.util.Util;
import org.olat.core.util.ZipUtil;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.SyncerCallback;
import org.olat.fileresource.types.AddingResourceException;
import org.olat.fileresource.types.AnimationFileResource;
import org.olat.fileresource.types.BlogFileResource;
import org.olat.fileresource.types.DocFileResource;
import org.olat.fileresource.types.FileResource;
import org.olat.fileresource.types.GlossaryResource;
import org.olat.fileresource.types.ImageFileResource;
import org.olat.fileresource.types.ImsCPFileResource;
import org.olat.fileresource.types.MovieFileResource;
import org.olat.fileresource.types.PdfFileResource;
import org.olat.fileresource.types.PodcastFileResource;
import org.olat.fileresource.types.PowerpointFileResource;
import org.olat.fileresource.types.ScormCPFileResource;
import org.olat.fileresource.types.SharedFolderFileResource;
import org.olat.fileresource.types.SoundFileResource;
import org.olat.fileresource.types.SurveyFileResource;
import org.olat.fileresource.types.TestFileResource;
import org.olat.fileresource.types.WikiResource;
import org.olat.fileresource.types.XlsFileResource;
import org.olat.modules.cp.CPOfflineReadableManager;
import org.olat.resource.OLATResource;
import org.olat.resource.OLATResourceManager;

/**
* Initial Date: Apr 8, 2004
*
* @author Mike Stock
*/
public class FileResourceManager {

  public static final String ZIPDIR = "_unzipped_";
  private static final FileResourceManager INSTANCE;

  private FileResourceManager() {
  // singleton
  }

  static {
    INSTANCE = new FileResourceManager();
  }

  /**
   * @return Singleton.
   */
  public static final FileResourceManager getInstance() {
    return INSTANCE;
  }

  /**
   * Add a file resource if the resource type is already known.
   *
   * @param fResource
   * @param newName
   * @param knownResource maybe null, FileResource type will be calculated
   * @return True upon success, false otherwise.
   */
  public FileResource addFileResource(File fResource, String newName, FileResource knownResource) throws AddingResourceException {

    // ZIPDIR is a reserved name... check
    if (fResource.getName().equals(ZIPDIR)) throw new AssertException("Trying to add FileResource with reserved name '" + ZIPDIR + "'.");

    FileResource tempFr = new FileResource();
    if (knownResource != null) tempFr = knownResource;

    // move file to its new place
    File fResourceFileroot = getFileResourceRoot(tempFr);
    if (!FileUtils.copyFileToDir(fResource, fResourceFileroot)) return null;

    if (!fResource.getName().equals(newName)) { // need to rename file to new
      // name
      File fNewName = new File(fResourceFileroot, newName);
      if (!new File(fResourceFileroot, fResource.getName()).renameTo(fNewName)) {
        FileUtils.deleteDirsAndFiles(fResourceFileroot, true, true);
        return null;
      }
      fResource = fNewName;
    }

    if (knownResource == null) {
      // save resourceableID
      Long resourceableId = tempFr.getResourceableId();
      // extract type
      try {
        if (DocFileResource.validate(fResource)) tempFr = new DocFileResource();
        else if (XlsFileResource.validate(fResource)) tempFr = new XlsFileResource();
        else if (PowerpointFileResource.validate(fResource)) tempFr = new PowerpointFileResource();
        else if (PdfFileResource.validate(fResource)) tempFr = new PdfFileResource();
        else if (ImageFileResource.validate(fResource)) tempFr = new ImageFileResource();
        else if (MovieFileResource.validate(fResource)) tempFr = new MovieFileResource();
        else if (SoundFileResource.validate(fResource)) tempFr = new SoundFileResource();
        else if (AnimationFileResource.validate(fResource)) tempFr = new AnimationFileResource();
        else if (SharedFolderFileResource.validate(fResource)) tempFr = new SharedFolderFileResource();
        // add a wiki copy
        else if (WikiResource.validate(fResource)) tempFr = new WikiResource();
        // add a podcast copy
        else if (PodcastFileResource.validate(fResource)) tempFr = new PodcastFileResource(fResourceFileroot, fResource);
        // add a blog copy
        else if (BlogFileResource.validate(fResource)) tempFr = new BlogFileResource(fResourceFileroot, fResource);
        // add a glossary copy
        else if (GlossaryResource.validate(fResource)) tempFr = new GlossaryResource();
        // the following types need unzippedDir
        else if (fResource.getName().toLowerCase().endsWith(".zip")) {
          File fUnzippedDir = unzipFileResource(tempFr);
          if (fUnzippedDir == null) {
            // in case of failure we forward the error message
            throw new AddingResourceException("resource.error.zip");
          }
          if (TestFileResource.validate(fUnzippedDir)) tempFr = new TestFileResource();
          else if (WikiResource.validate(fUnzippedDir)) tempFr = new WikiResource();
          else if (PodcastFileResource.validate(fUnzippedDir)) tempFr = new PodcastFileResource(fResourceFileroot, fUnzippedDir);
          else if (BlogFileResource.validate(fUnzippedDir)) tempFr = new BlogFileResource(fResourceFileroot, fUnzippedDir);
          else if (SurveyFileResource.validate(fUnzippedDir)) tempFr = new SurveyFileResource();
          // CP must be later entry... Test- and SurveyFileResource may contain
          // imsmanifest.xml as well
          else if (ImsCPFileResource.validate(fUnzippedDir)) tempFr = new ImsCPFileResource();
          // scorm and cp now can throw an exception which helps to show a
          // better error message in case
          // of a failure in adding a new resource
          else if (ScormCPFileResource.validate(fUnzippedDir)) tempFr = new ScormCPFileResource();
          // glossary resources are packaged within zip for import/export
          else if (GlossaryResource.validate(fUnzippedDir)) tempFr = new GlossaryResource();
          else {
            // just a generic ZIP file... we can delete the temporary unziped
            // dir...
            throw new AddingResourceException("doesn't matter what error key is declared");
          }
        }
      } catch (AddingResourceException exception) {
        // in case of failure we delete the resource and forward the error
        // message
        deleteFileResource(tempFr);
        throw exception;
      }

      tempFr.overrideResourceableId(resourceableId);
    }

    // add olat resource
    OLATResourceManager rm = OLATResourceManager.getInstance();
    OLATResource ores = rm.findOrPersistResourceable(tempFr);

    // make IMS-Content-Packaging offline readable adding a html-frameset
    if (tempFr instanceof ImsCPFileResource) {
      CPOfflineReadableManager cporm = CPOfflineReadableManager.getInstance();
      cporm.makeCPOfflineReadable(ores, newName);
    }
    return tempFr;
  }

  /**
   * @param fResource
   * @param newName
   * @return Newly created file resource
   */
  public FileResource addFileResource(File fResource, String newName) throws AddingResourceException {
    return addFileResource(fResource, newName, null);
  }

  /**
   * @param res
   */
  public void deleteFileResource(OLATResourceable res) {
    // delete resources
    File fResourceFileroot = getFileResourceRoot(res);
    FileUtils.deleteDirsAndFiles(fResourceFileroot, true, true);
    // delete resourceable
    OLATResourceManager rm = OLATResourceManager.getInstance();
    OLATResource ores = rm.findResourceable(res);
    if (ores != null) rm.deleteOLATResource(ores);
  }

  /**
   * @param res
   * @return Canonical root of file resource
   */
  public File getFileResourceRoot(OLATResourceable res) {
    return getFileResourceRootImpl(res).getBasefile();
  }

  /**
   * @param res
   * @return olat root folder implementation of file resource
   */
  public OlatRootFolderImpl getFileResourceRootImpl(OLATResourceable res) {
    return new OlatRootFolderImpl(FolderConfig.getRepositoryHome() + "/" + res.getResourceableId(), null);
  }

  /**
   * @param res
   * @return Get resourceable as file.
   */
  public File getFileResource(OLATResourceable res) {
    return getFileResource(res, null);
  }

  /**
   * @param res
   * @return Get resourceable as file.
   */
  private File getFileResource(OLATResourceable res, String resourceFolderName) {
    FileResource fr = getAsGenericFileResource(res);
    File f = getFile(fr, resourceFolderName);
    if (f == null) // folder not existing or no file in it
    throw new OLATRuntimeException(FileResourceManager.class, "could not getFileResource for OLATResourceable " + res.getResourceableId()
        + ":" + res.getResourceableTypeName(), null);
    return f;
  }

  /**
   * Get the specified file or the first zip archive.
   *
   * @param fr
   * @return The specified file, the first zip archive or null
   */
  private File getFile(FileResource fr) {
    return getFile(fr, null);
  }

  /**
   * Get the specified file or the first zip archive.
   *
   * @param fr
   * @param resourceFolderName
   * @return The specified file, the first zip archive or null
   */
  private File getFile(FileResource fr, String resourceFolderName) {
    File fResourceFileroot = getFileResourceRoot(fr);
    if (!fResourceFileroot.exists()) return null;
    File[] contents = fResourceFileroot.listFiles();
    File firstFile = null;
    for (int i = 0; i < contents.length; i++) {
      File file = contents[i];
      if (file.getName().equals(ZIPDIR)) continue; // skip ZIPDIR

      if (resourceFolderName != null) {
        // search for specific file name
        if (file.getName().equals(resourceFolderName)) { return file; }
      } else if (file.getName().toLowerCase().endsWith(".zip")) {
        // we use first zip file we find
        return file;
      } else if (firstFile == null) {
        // store the first file to be able to return it later. this is needed
        // for wikis.
        firstFile = file;
      }

    }
    // Neither the specified resource nor any zip file could be found. Return
    // the first file that is not ZIPDIR or null.
    return firstFile;
  }

  /**
   * @param res
   * @return File resource as downloadeable media resource.
   */
  public MediaResource getAsDownloadeableMediaResource(OLATResourceable res) {
    FileResource fr = getAsGenericFileResource(res);
    File f = getFile(fr);
    if (f == null) // folder not existing or no file in it
    throw new OLATRuntimeException(FileResourceManager.class, "could not get File for OLATResourceable " + res.getResourceableId() + ":"
        + res.getResourceableTypeName(), null);
    return new DownloadeableMediaResource(f);
  }

  /**
   * @param res
   * @return Directory wherer unzipped files of file resourcea are located.
   */
  public String getUnzippedDirRel(OLATResourceable res) {
    return res.getResourceableId() + "/" + ZIPDIR;
  }

  /**
   * Unzips a resource and returns the unzipped folder's root.
   *
   * @param res
   * @return Unzip contents of ZIP file resource.
   */
  public File unzipFileResource(final OLATResourceable res) {
    final File dir = getFileResourceRoot(res);
    if (!dir.exists()) return null;
    File zipTargetDir = new File(dir, ZIPDIR);
    if (!zipTargetDir.exists()) {
      // if not unzipped yet, synchronize all unzipping processes
      // o_clusterOK by:ld
      zipTargetDir = CoordinatorManager.getCoordinator().getSyncer().doInSync(res, new SyncerCallback<File>() {
        public File execute() {
          File zipTargetDir = null;
          // now we are the only one unzipping. We
          // only need to unzip when the previous
          // threads that aquired this lock have not unzipped "our" version's
          // resources yet
          zipTargetDir = new File(dir, ZIPDIR);
          if (!zipTargetDir.exists()) { // means I am the first to unzip this
            // version's resource
            zipTargetDir.mkdir();
            File zipFile = getFileResource(res);
            if (!ZipUtil.unzip(zipFile, zipTargetDir)) return null;
          }
          return zipTargetDir;
        }
      });
    }
    return zipTargetDir;
  }

  /**
   * Deletes the contents of the last unzip operation.
   *
   * @param res
   * @return True upon success.
   */
  public boolean deleteUnzipContent(OLATResourceable res) {
    File dir = getFileResourceRoot(res);
    if (!dir.exists()) return false;
    File zipTargetDir = new File(dir, ZIPDIR);
    return FileUtils.deleteDirsAndFiles(zipTargetDir, true, true);
  }

  /**
   * @param res
   * @param locale
   * @return Components displaying details of a file resource.
   */
  public Component getDetailsComponent(OLATResourceable res, Locale locale) {
    Translator translator = Util.createPackageTranslator(this.getClass(), locale);
    return new FileDetailsForm("fileDetails", translator, res);
  }

  private FileResource getAsGenericFileResource(OLATResourceable res) {
    FileResource fr = new FileResource();
    fr.overrideResourceableId(res.getResourceableId());
    return fr;
  }

  /**
   * Creates a copy of the given resourceable.
   *
   * @param res
   * @return Copy of the given resource.
   */
  public OLATResourceable createCopy(OLATResourceable res) {
    return createCopy(res, null);
  }

  /**
   * Creates a copy of the given resourceable.
   *
   * @param res
   * @return Copy of the given resource.
   */
  public OLATResourceable createCopy(OLATResourceable res, String resourceFolderName) {
    File fResource = getFileResource(res, resourceFolderName);
    if (fResource == null) return null;
    try {
      return addFileResource(fResource, fResource.getName());
    } catch (AddingResourceException e) {
      throw new OLATRuntimeException(FileResourceManager.class, "Error while trying to copy resource with name: " + fResource.getName(), e);
    }
  }

}
TOP

Related Classes of org.olat.fileresource.FileResourceManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.