/**
* OLAT - Online Learning and Training
* http://www.olat.org
*
* 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.
*
* Copyright (c) 1999-2007 at Multimedia- & E-Learning Services (MELS),
* University of Zurich, Switzerland.
*
*/ package org.olat.ims.cp; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; import org.dom4j.tree.DefaultDocument; import org.dom4j.tree.DefaultElement; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.util.CodeHelper; import org.olat.core.util.FileUtils; import org.olat.core.util.ZipUtil; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.xml.XMLParser; import org.olat.fileresource.FileResourceManager; import org.olat.ims.cp.objects.CPOrganization; import org.olat.ims.cp.objects.CPResource; import org.olat.ims.cp.ui.CPPage; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; /** * The CP manager implementation. *
* In many cases, method calls are delegated to the content package object. * *
* Initial Date: 04.07.2008
*
* @author Sergio Trentini
*/
public class CPManagerImpl extends CPManager {
/**
* [spring]
*/
private CPManagerImpl() {
INSTANCE = this;
}
/**
*
* @see org.olat.ims.cp.CPManager#load(org.olat.core.util.vfs.VFSContainer)
*/
public ContentPackage load(VFSContainer directory, OLATResourceable ores) {
XMLParser parser = new XMLParser();
ContentPackage cp;
VFSLeaf file = (VFSLeaf) directory.resolve("imsmanifest.xml");
if (file != null) {
try {
DefaultDocument doc = (DefaultDocument) parser.parse(file.getInputStream(), false);
cp = new ContentPackage(doc, directory, ores);
// If a wiki is imported or a new cp created, set a unique orga
// identifier.
if (cp.getLastError() == null) {
if (cp.isOLATContentPackage() && CPCore.OLAT_ORGANIZATION_IDENTIFIER.equals(cp.getFirstOrganizationInManifest().getIdentifier())) {
setUniqueOrgaIdentifier(cp);
}
}
} catch (OLATRuntimeException e) {
cp = new ContentPackage(null, directory, ores);
logError("Reading imsmanifest failed. Dir: " + directory.getName() + ". Ores: " + ores.getResourceableId(), e);
cp.setLastError("Exception reading XML for IMS CP: invalid xml-file ( " + directory.getName() + ")");
}
} else {
cp = new ContentPackage(null, directory, ores);
cp.setLastError("Exception reading XML for IMS CP: IMS-Manifest not found in " + directory.getName());
logError("IMS manifiest xml couldn't be found in dir " + directory.getName() + ". Ores: " + ores.getResourceableId(), null);
throw new OLATRuntimeException(CPManagerImpl.class, "The imsmanifest.xml file was not found.", new IOException());
}
return cp;
}
/**
* @see org.olat.ims.cp.CPManager#createNewCP(org.olat.core.id.OLATResourceable)
*/
public ContentPackage createNewCP(OLATResourceable ores, String initalPageTitle) {
// copy template cp to new repo-location
if (copyTemplCP(ores)) {
File cpRoot = FileResourceManager.getInstance().unzipFileResource(ores);
logDebug("createNewCP: cpRoot=" + cpRoot);
logDebug("createNewCP: cpRoot.getAbsolutePath()=" + cpRoot.getAbsolutePath());
System.out.println("createNewCP: cpRoot.getAbsolutePath()=" + cpRoot.getAbsolutePath());
LocalFolderImpl vfsWrapper = new LocalFolderImpl(cpRoot);
ContentPackage cp = load(vfsWrapper, ores);
// Modify the copy of the template to get a unique identifier
CPOrganization orga = setUniqueOrgaIdentifier(cp);
setOrgaTitleToRepoEntryTitle(ores, orga);
// Also set the translated title of the inital page.
orga.getItems().get(0).setTitle(initalPageTitle);
writeToFile(cp);
return cp;
} else {
logError("CP couldn't be created. Error when copying template. Ores: " + ores.getResourceableId(), null);
throw new OLATRuntimeException("ERROR while creating new empty cp. an error occured while trying to copy template CP", null);
}
}
/**
* Sets the organization title to the title of the repository entry.
*
* @param ores
* @param orga
*/
private void setOrgaTitleToRepoEntryTitle(OLATResourceable ores, CPOrganization orga) {
// Set the title of the organization to the title of the resource.
RepositoryManager resMgr = RepositoryManager.getInstance();
RepositoryEntry cpEntry = resMgr.lookupRepositoryEntry(ores, false);
if (cpEntry != null) {
String title = cpEntry.getDisplayname();
orga.setTitle(title);
}
}
/**
* Assigns the organization a unique identifier in order to prevent any
* caching issues in the extjs menu tree later.
*
* @param cp
* @return The first organization of the content package.
*/
private CPOrganization setUniqueOrgaIdentifier(ContentPackage cp) {
CPOrganization orga = cp.getFirstOrganizationInManifest();
String newOrgaIdentifier = "olatcp-" + CodeHelper.getForeverUniqueID();
orga.setIdentifier(newOrgaIdentifier);
return orga;
}
public boolean isSingleUsedResource(CPResource res, ContentPackage cp) {
return cp.isSingleUsedResource(res);
}
@Override
public String addBlankPage(ContentPackage cp, String title) {
return cp.addBlankPage(title);
}
@Override
public String addBlankPage(ContentPackage cp, String title, String parentNodeID) {
return cp.addBlankPage(parentNodeID, title);
}
@Override
public void updatePage(ContentPackage cp, CPPage page) {
cp.updatePage(page);
}
/**
* @see org.olat.ims.cp.CPManager#addElement(org.olat.ims.cp.ContentPackage,
* org.dom4j.tree.DefaultElement)
*/
public boolean addElement(ContentPackage cp, DefaultElement newElement) {
return cp.addElement(newElement);
}
/**
* @see org.olat.ims.cp.CPManager#addElement(org.olat.ims.cp.ContentPackage,
* org.dom4j.tree.DefaultElement, java.lang.String)
*/
public boolean addElement(ContentPackage cp, DefaultElement newElement, String parentIdentifier, int position) {
return cp.addElement(newElement, parentIdentifier, position);
}
/**
*
* @see org.olat.ims.cp.CPManager#addElementAfter(org.olat.ims.cp.ContentPackage,
* org.dom4j.tree.DefaultElement, java.lang.String)
*/
public boolean addElementAfter(ContentPackage cp, DefaultElement newElement, String identifier) {
return cp.addElementAfter(newElement, identifier);
}
/**
*
* @see org.olat.ims.cp.CPManager#removeElement(org.olat.ims.cp.ContentPackage,
* java.lang.String)
*/
public void removeElement(ContentPackage cp, String identifier, boolean deleteResource) {
cp.removeElement(identifier, deleteResource);
}
/**
* @see org.olat.ims.cp.CPManager#moveElement(org.olat.ims.cp.ContentPackage,
* java.lang.String, java.lang.String, int)
*/
public void moveElement(ContentPackage cp, String nodeID, String newParentID, int position) {
cp.moveElement(nodeID, newParentID, position);
}
/**
*
* @see org.olat.ims.cp.CPManager#copyElement(org.olat.ims.cp.ContentPackage,
* java.lang.String)
*/
public String copyElement(ContentPackage cp, String sourceID) {
return cp.copyElement(sourceID, sourceID);
}
/**
* @see org.olat.ims.cp.CPManager#getDocument(org.olat.ims.cp.ContentPackage)
*/
public DefaultDocument getDocument(ContentPackage cp) {
return cp.getDocument();
}
public String getItemTitle(ContentPackage cp, String itemID) {
return cp.getItemTitle(itemID);
}
/**
* @see org.olat.ims.cp.CPManager#getElementByIdentifier(org.olat.ims.cp.ContentPackage,
* java.lang.String)
*/
public DefaultElement getElementByIdentifier(ContentPackage cp, String identifier) {
return cp.getElementByIdentifier(identifier);
}
@Override
public CPTreeDataModel getTreeDataModel(ContentPackage cp) {
return cp.buildTreeDataModel();
}
/**
*
* @see org.olat.ims.cp.CPManager#getFirstOrganizationInManifest(org.olat.ims.cp.ContentPackage)
*/
@Override
public CPOrganization getFirstOrganizationInManifest(ContentPackage cp) {
return cp.getFirstOrganizationInManifest();
}
/**
*
* @see org.olat.ims.cp.CPManager#getFirstPageToDisplay(org.olat.ims.cp.ContentPackage)
*/
@Override
public CPPage getFirstPageToDisplay(ContentPackage cp) {
return cp.getFirstPageToDisplay();
}
/**
* @see org.olat.ims.cp.CPManager#WriteToFile(org.olat.ims.cp.ContentPackage)
*/
public void writeToFile(ContentPackage cp) {
cp.writeToFile();
}
/**
* @see org.olat.ims.cp.CPManager#writeToZip(org.olat.ims.cp.ContentPackage)
*/
public VFSLeaf writeToZip(ContentPackage cp) {
OLATResourceable ores = cp.getResourcable();
VFSContainer cpRoot = cp.getRootDir();
VFSContainer oresRoot = FileResourceManager.getInstance().getFileResourceRootImpl(ores);
RepositoryEntry repoEntry = RepositoryManager.getInstance().lookupRepositoryEntry(ores, false);
String zipFileName = "imscp.zip";
if (repoEntry != null) {
String zipName = repoEntry.getResourcename();
if (zipName != null && zipName.endsWith(".zip")) {
zipFileName = zipName;
}
}
// delete old archive and create new one
VFSItem oldArchive = oresRoot.resolve(zipFileName);
if (oldArchive != null) {
oldArchive.delete();
}
ZipUtil.zip(cpRoot.getItems(), oresRoot.createChildLeaf(zipFileName));
VFSLeaf zip = (VFSLeaf) oresRoot.resolve(zipFileName);
return zip;
}
/**
*
* @see org.olat.ims.cp.CPManager#getPageByItemId(org.olat.ims.cp.ContentPackage,
* java.lang.String)
*/
@Override
public String getPageByItemId(ContentPackage cp, String itemIdentifier) {
return cp.getPageByItemId(itemIdentifier);
}
/**
* copies the default,empty, cp template to the new ores-directory
*
* @param ores
* @return
*/
private boolean copyTemplCP(OLATResourceable ores) {
File root = FileResourceManager.getInstance().getFileResourceRoot(ores);
String packageName = ContentPackage.class.getCanonicalName();
String path = packageName.replace('.', '/');
path = path.replace("/ContentPackage", "/_resources/imscp.zip");
path = VFSManager.sanitizePath(path);
URL url = this.getClass().getResource(path);
try {
File f = new File(url.toURI());
if (f.exists() && root.exists()) {
FileUtils.copyFileToDir(f, root);
} else {
logError("cp template was not copied. Source: " + url + " Target: " + root.getAbsolutePath(), null);
}
} catch (URISyntaxException e) {
logError("Bad url syntax when copying cp template. url: " + url + " Ores:" + ores.getResourceableId(), null);
return false;
}
return true;
}
}