package net.sourceforge.fenixedu.integration.server; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.LogFactory; import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeManager; import org.dspace.content.Bitstream; import org.dspace.content.BitstreamFormat; import org.dspace.content.Bundle; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.DCValue; import org.dspace.content.DSpaceFileManagerUtilities; import org.dspace.content.DSpaceObject; import org.dspace.content.FormatIdentifier; import org.dspace.content.Item; import org.dspace.content.ItemIterator; import org.dspace.core.ConfigurationManager; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.handle.HandleManager; import org.dspace.search.DSIndexer; import org.dspace.search.DSQuery; import pt.utl.ist.fenix.tools.file.FileDescriptor; import pt.utl.ist.fenix.tools.file.FileSet; import pt.utl.ist.fenix.tools.file.FileSetDescriptor; import pt.utl.ist.fenix.tools.file.FileSetMetaData; import pt.utl.ist.fenix.tools.file.FileSetQueryResults; import pt.utl.ist.fenix.tools.file.FilesetMetadataQuery; import pt.utl.ist.fenix.tools.file.VirtualPath; import pt.utl.ist.fenix.tools.file.VirtualPathNode; import pt.utl.ist.fenix.tools.file.utils.FileUtils; import pt.utl.ist.fenix.tools.tree.TreeUtilities; import pt.utl.ist.fenix.tools.tree.TreeUtilities.TreeRecurseException; public class DSpaceRemoteManager { private static DSpaceRemoteManager instance = new DSpaceRemoteManager(); private static Integer lock = Integer.valueOf(1); private DSpaceRemoteManager() { } private static DSpaceRemoteManager getInstance() { return instance; } private static final String FENIX_GROUP_NAME = ConfigurationManager.getProperty("fenix.groupName"); public static File materializeFileSetAtTemporaryDirectory(Context ctx, FileSetDescriptor descriptor) throws DSpaceRemoteManagerException { File tempDir; try { tempDir = FileUtils.createTemporaryDir("DspaceTmpDownload", "tmp"); String basePath = descriptor.getAllFileDescriptors().toArray(new FileDescriptor[0])[0] .getOriginalAbsoluteFilePath(); File f = new File(basePath); basePath = f.getParent(); recursiveMaterializeFileSet(descriptor, ctx, tempDir, basePath); return tempDir; } catch (IOException e) { throw new DSpaceRemoteManagerException(e); } } public static FileSet recursiveMaterializeFileSet(FileSetDescriptor descriptor, Context ctx, File tempDir, String basePath) throws DSpaceRemoteManagerException { FileSet retVal = materializeFileSetAtLevel(descriptor, ctx, tempDir, basePath); for (FileSetDescriptor childDescriptor : descriptor.getChildSets()) retVal.addChildSet(recursiveMaterializeFileSet(childDescriptor, ctx, tempDir, basePath)); return retVal; } public static FileSet materializeFileSetAtLevel(FileSetDescriptor descriptor, Context ctx, File tempDir, String basePath) throws DSpaceRemoteManagerException { FileSet retVal = descriptor.createBasicFileSet(); String firstBitStreamIdentifier = descriptor.getAllFileDescriptors().toArray(new FileDescriptor[0])[0] .getUniqueId(); retVal.getMetaInfo().clear(); Item item = getItemForTheBitStream(ctx, firstBitStreamIdentifier); DCValue[] dublinCores = item.getDC(Item.ANY, Item.ANY, Item.ANY); if (dublinCores != null) for (DCValue dc : dublinCores) retVal.addMetaInfo(new FileSetMetaData(dc.element, dc.qualifier, dc.language, dc.value)); for (FileDescriptor fileDesc : descriptor.getAllFileDescriptors()) { String bitStreamIdentifier = fileDesc.getUniqueId(); Bitstream bs = resolveBitStream(ctx, bitStreamIdentifier); File resultFile = materializeFile(bs, tempDir, basePath); retVal.replaceFileWithAbsolutePath(fileDesc.getOriginalAbsoluteFilePath(), resultFile); } return retVal; } public static Bitstream materializeBitstream(Context ctx, String bitStreamUniqueId) throws DSpaceRemoteManagerException { return resolveBitStream(ctx, bitStreamUniqueId); } public static File materializeFile(Bitstream currentBitStream, File tempDir, String basePath) throws DSpaceRemoteManagerException { String absoluteFilePath = currentBitStream.getSource(); if (!absoluteFilePath.startsWith(basePath)) throw new DSpaceRemoteManagerException("bitstream with absolute path " + absoluteFilePath + " is not inside the basePath " + basePath); String relativeFilePath = absoluteFilePath.substring(basePath.length()); File destinationFile = new File(tempDir, relativeFilePath); if (destinationFile.getParentFile() != null) destinationFile.mkdirs(); try { destinationFile.createNewFile(); } catch (IOException e) { throw new DSpaceRemoteManagerException(e.getMessage(), e); } destinationFile.deleteOnExit(); InputStream srcStream; try { srcStream = currentBitStream.retrieve(); OutputStream outStream = new FileOutputStream(destinationFile); FileUtils.copyInputStreamToOutputStream(srcStream, outStream); } catch (IOException e) { throw new DSpaceRemoteManagerException(e); } catch (SQLException e) { throw new DSpaceRemoteManagerException(e); } catch (AuthorizeException e) { throw new DSpaceRemoteManagerException(e); } return destinationFile; } /** * @param context * @param destination * The hierarchical name the collection that will store the item * (e.g. Community->Sub Community->Sub Community 2 ->The * Collection) * @param file * the file to save * @param originalFilename * The filesystem name of the file * @param uploadedItemMetadata * The item metadata (Dublin core metadata subset) * @return FileSetDescriptor * @throws IOException * @throws AuthorizeException * @throws SQLException */ public static FileSetDescriptor uploadFileSet(Context ctx, FileSet fs, String originalFileName, VirtualPath vPath, boolean privateFile) throws DSpaceRemoteManagerException { boolean rollback = false; try { if (vPath.getNodes().size() < 2) { rollback = true; throw new DSpaceRemoteManagerException( "Collection cannot be created at top level. At least one community is required"); } VirtualPathNode collectionPathNode = vPath.getNodes().get(vPath.getNodes().size() - 1); Community community = getOrCreateCommunity(ctx, vPath); Collection collection = getOrCreateCollection(community, collectionPathNode); // check permissions top level, and not on every insert... AuthorizeManager.authorizeAction(ctx, collection, Constants.ADD); return recursiveCreateFileSet(ctx, collection, fs, originalFileName, privateFile); } catch (AuthorizeException e) { rollback = true; throw new DSpaceRemoteManagerException("not.authorized"); } catch (Exception e) { rollback = true; throw new DSpaceRemoteManagerException(e.getMessage()); } finally { if (rollback == true) { ctx.abort(); } else { try { ctx.complete(); } catch (SQLException e) { throw new DSpaceRemoteManagerException(e.getMessage()); } } } } public static FileSetDescriptor addFileToItem(Context context, FileSet fs, boolean privateFile) throws DSpaceRemoteManagerException { boolean rollback = false; try { return addFileSetToExistingItem(context, fs, privateFile); } catch (SQLException e) { rollback = true; throw new DSpaceRemoteManagerException(e.getMessage()); } catch (AuthorizeException e) { rollback = true; throw new DSpaceRemoteManagerException("not.authorized"); } catch (IOException e) { rollback = true; throw new DSpaceRemoteManagerException(e.getMessage()); } finally { if (rollback) { context.abort(); } else { try { context.complete(); } catch (SQLException e) { throw new DSpaceRemoteManagerException(e.getMessage()); } } } } public static void removeFileFromItem(Context context, String uniqueId) throws DSpaceRemoteManagerException { boolean roolback = false; try { deleteFile(context, uniqueId); } catch (DSpaceRemoteManagerException e) { roolback = true; } catch (SQLException e) { roolback = true; } catch (AuthorizeException e) { roolback = true; } catch (IOException e) { roolback = true; } finally { if (roolback) { context.abort(); } else { try { context.complete(); } catch (SQLException e) { throw new DSpaceRemoteManagerException(e.getMessage()); } } } } public static void deleteFileSet(Context context, FileSetDescriptor descriptor) throws DSpaceRemoteManagerException { boolean rollback = false; try { recurseObjectTree(descriptor, "deleteFileSetAtLevel", new Class[] { Context.class }, new Object[] { context }); } catch (AuthorizeException e) { rollback = true; throw new DSpaceRemoteManagerException("not.authorized"); } catch (Exception e) { rollback = true; throw new DSpaceRemoteManagerException(e.getMessage()); } finally { if (rollback == true) { context.abort(); } else { try { context.complete(); } catch (SQLException e) { throw new DSpaceRemoteManagerException(e.getMessage()); } } } } public void deleteFileSetAtLevel(FileSetDescriptor descriptor, Context ctx) throws DSpaceRemoteManagerException, SQLException, AuthorizeException, IOException { for (FileDescriptor fileDesc : descriptor.getAllFileDescriptors()) { String bitStreamId = fileDesc.getUniqueId(); try { deleteFile(ctx, bitStreamId); } catch (Exception e) { throw new DSpaceRemoteManagerException("delete.bitstream.problem.id." + bitStreamId); } } } /*************************************************************************** * Deletes a file from repository * * @param context * @param bitstreamIdentification ( * //) * @throws DSpaceRemoteManagerException * @throws SQLException * @throws IOException * @throws AuthorizeException */ private static void deleteFile(Context context, String bitstreamIdentification) throws DSpaceRemoteManagerException, SQLException, AuthorizeException, IOException { String itemHandle = bitstreamIdentification.substring(0, bitstreamIdentification.lastIndexOf("/")); int bitStreamSequenceNumber = Integer.parseInt(bitstreamIdentification .substring(bitstreamIdentification.lastIndexOf("/") + 1)); Item item = (Item) HandleManager.resolveToObject(context, itemHandle); if (item == null || item.getBundles() == null || item.getBundles().length == 0) { return ; } Bitstream removeBitStream = null; for (Bundle bundle : item.getBundles()) { if (bundle.getBitstreams() != null) { for (Bitstream bitStream : bundle.getBitstreams()) { if (bitStream.getSequenceID() == bitStreamSequenceNumber) { removeBitStream = bitStream; break; } } if (removeBitStream != null) { bundle.removeBitstream(removeBitStream); unIndexContent(context, removeBitStream); break; } } } int totalBitStreams = 0; for (Bundle bundle : item.getBundles()) { if (bundle.getBitstreams() != null) { totalBitStreams += bundle.getBitstreams().length; } } if (removeBitStream == null) throw new DSpaceRemoteManagerException("file.not.found"); if (totalBitStreams == 0) { for (Collection col : item.getCollections()) { col.removeItem(item); } unIndexContent(context, item); } } public static void changeFileSetPermissions(Context context, FileSetDescriptor descriptor, boolean privateFile) throws DSpaceRemoteManagerException { boolean rollback = false; try { recurseObjectTree(descriptor, "changeFileSetPermissionsAtLevel", new Class[] { Context.class, boolean.class }, new Object[] { context, privateFile }); } catch (AuthorizeException e) { rollback = true; throw new DSpaceRemoteManagerException("not.authorized"); } catch (Exception e) { rollback = true; throw new DSpaceRemoteManagerException(e.getMessage()); } finally { if (rollback == true) { context.abort(); } else { try { context.complete(); } catch (SQLException e) { throw new DSpaceRemoteManagerException(e.getMessage()); } } } } public void changeFileSetPermissionsAtLevel(FileSetDescriptor descriptor, Context ctx, boolean privateFile) throws DSpaceRemoteManagerException, SQLException, AuthorizeException { for (FileDescriptor fileDesc : descriptor.getAllFileDescriptors()) { String bitStreamId = fileDesc.getUniqueId(); changeFilePermissions(ctx, bitStreamId, privateFile); } } public static void changeItemMetaData(Context context, String itemHandle, java.util.Collection metaData) throws DSpaceRemoteManagerException { boolean rollBack = false; try { Item item = Item.find(context, DSpaceFileManagerUtilities.getItemId(context, itemHandle)); item.clearDC(Item.ANY, Item.ANY, Item.ANY); for (FileSetMetaData metaDataElement : metaData) { item.addDC(metaDataElement.getElement(), metaDataElement.getQualifier(), metaDataElement .getLang(), metaDataElement.getValues()); item.update(); reIndexContent(context, item); } } catch (SQLException e) { rollBack = true; throw new DSpaceRemoteManagerException(e.getMessage()); } catch (AuthorizeException e) { rollBack = true; throw new DSpaceRemoteManagerException("not.authorized"); } catch (IOException e) { rollBack = true; throw new DSpaceRemoteManagerException(e.getMessage()); } finally { if (rollBack) { context.abort(); } else { try { context.complete(); } catch (SQLException e) { throw new DSpaceRemoteManagerException(e.getMessage()); } } } } public static void changeFilePermissions(Context context, String bitstreamIdentification, boolean privateFile) throws DSpaceRemoteManagerException, SQLException, AuthorizeException { int lastIndexOfSlash = bitstreamIdentification.lastIndexOf("/"); String itemHandle = bitstreamIdentification.substring(0, lastIndexOfSlash); int bitstreamSequenceId = Integer.parseInt(bitstreamIdentification.substring(lastIndexOfSlash + 1)); Item item = (Item) HandleManager.resolveToObject(context, itemHandle); Bitstream bitstream = getBistreamFromItemByBitstreamSequenceId(item, bitstreamSequenceId); if (item == null || bitstream == null) { throw new DSpaceRemoteManagerException("file.not.Found"); } else { setItemPolicies(context, item, privateFile); setBitstreamPolicies(context, bitstream, privateFile); } } private static void setItemPolicies(Context context, Item item, boolean isPrivate) throws SQLException, AuthorizeException { AuthorizeManager.removeAllPolicies(context, item); Group group = null; if (isPrivate) { group = Group.findByName(context, FENIX_GROUP_NAME); } else { group = Group.find(context, 0); // public } AuthorizeManager.addPolicy(context, item, Constants.READ, group); AuthorizeManager.addPolicy(context, item, Constants.DEFAULT_BITSTREAM_READ, group); AuthorizeManager.addPolicy(context, item, Constants.DEFAULT_ITEM_READ, group); } private static void setBitstreamPolicies(Context context, Bitstream bitstream, boolean isPrivate) throws SQLException, AuthorizeException { AuthorizeManager.removeAllPolicies(context, bitstream); Group group = null; if (isPrivate) { group = Group.findByName(context, FENIX_GROUP_NAME); } else { group = Group.find(context, 0); // public } AuthorizeManager.addPolicy(context, bitstream, Constants.READ, group); AuthorizeManager.addPolicy(context, bitstream, Constants.DEFAULT_BITSTREAM_READ, group); AuthorizeManager.addPolicy(context, bitstream, Constants.DEFAULT_ITEM_READ, group); } private static Community getOrCreateCommunity(Context context, VirtualPath path) throws SQLException, AuthorizeException, IOException { Community community = null; Community parentCommunity = null; for (int i = 0; i < path.getNodes().size() - 1; i++) { VirtualPathNode pathNode = path.getNodes().get(i); String communityName = pathNode.getName(); String communityDescription = pathNode.getDescription(); community = Community.findByNameAndLevel(context, parentCommunity, communityName); if (community == null) { // Community does not exists, so ensure path community = Community.create(parentCommunity, context); community.setMetadata("name", communityName); community.setMetadata("short_description", communityDescription); community.update(); if (parentCommunity != null) { parentCommunity.addSubcommunity(community); } } parentCommunity = community; } return community; } private static Community getCommunity(Context context, VirtualPath path) throws SQLException, AuthorizeException { Community community = null; Community parentCommunity = null; for (int i = 0; i < path.getNodes().size(); i++) { VirtualPathNode pathNode = path.getNodes().get(i); String communityName = pathNode.getName(); community = Community.findByNameAndLevel(context, parentCommunity, communityName); if (community == null) { return null; } if (parentCommunity != null) { parentCommunity.addSubcommunity(community); } parentCommunity = community; } return community; } private static Collection getOrCreateCollection(Community community, VirtualPathNode collectionPathNode) throws SQLException, AuthorizeException, IOException { Collection[] collectionsInCommunity = community.getCollections(); Collection result = null; for (Collection collection : collectionsInCommunity) { if (collection.getMetadata("name").equals(collectionPathNode.getName())) { result = collection; } } if (result == null) { result = community.createCollection(); result.setMetadata("name", collectionPathNode.getName()); result.setMetadata("short_description", collectionPathNode.getDescription()); result.update(); } return result; } private static Bitstream getBistreamFromItemByBitstreamSequenceId(Item item, int bitstreamSequenceId) { Bundle[] bundles = item.getBundles(); for (int i = 0; i < bundles.length; i++) { Bitstream[] bitstreams = bundles[i].getBitstreams(); for (int j = 0; j < bitstreams.length; j++) { if (bitstreams[j].getSequenceID() == bitstreamSequenceId) { return bitstreams[j]; } } } return null; } public static boolean authenticateAndCheckIfIsAdmin(Context context, String username, String password) throws DSpaceRemoteManagerException { try { boolean success = false; EPerson person = EPerson.findByNetid(context, username); if (person != null && person.checkPassword(password)) { context.setCurrentUser(person); if (AuthorizeManager.isAdmin(context)) { success = true; } } return success; } catch (SQLException e) { throw new DSpaceRemoteManagerException(e.getMessage()); } } private static void setItemPath(Item item, String itemPath) { item.addDC("location", "item.path", null, itemPath); } private static String getItemPath(Item item) { DCValue[] values = item.getDC("location", "item.path", null); return (values.length == 0) ? item.getHandle() : values[0].value.toString(); } private static FileSetDescriptor recursiveCreateFileSet(Context ctx, Collection collection, FileSet fs, String itemPath, boolean privateFile) throws AuthorizeException, SQLException, IOException { FileSetDescriptor descriptor = createFileSetAtLevel(ctx, collection, itemPath, fs, privateFile); int childSetCount = 0; for (FileSet childSet : fs.getChildSets()) { descriptor.addChildSet(recursiveCreateFileSet(ctx, collection, childSet, itemPath + "/" + childSetCount, privateFile)); ++childSetCount; } return descriptor; } private static Integer getNextBitStreamIdForBundle(Bundle bundle) { Bitstream[] bitstreams = bundle.getBitstreams(); int max = -1; for (Bitstream bitstream : bitstreams) { max = Math.max(max, bitstream.getSequenceID()); } return max + 1; } private static FileSetDescriptor addFileSetToExistingItem(Context context, FileSet fs, boolean privateFile) throws SQLException, AuthorizeException, IOException { Item item = Item.find(context, DSpaceFileManagerUtilities.getItemId(context, fs.getItemHandle())); Bundle contentBundle = item.getBundles("ORIGINAL")[0]; BufferedInputStream contentFileStream = null; for (File f : fs.getContentFiles()) { contentFileStream = new BufferedInputStream(new FileInputStream(f)); Bitstream bitStream = contentBundle.createBitstream(contentFileStream); bitStream.setName(f.getName()); bitStream.setSource(f.getAbsolutePath()); bitStream.setFormat(FormatIdentifier.guessFormat(context, bitStream)); setBitstreamPolicies(context, bitStream, privateFile); contentBundle.update(); bitStream.update(); } item.update(); FileSetDescriptor descriptor = new FileSetDescriptor(); for (Bitstream bitStream : contentBundle.getBitstreams()) { FileDescriptor fileDesc = new FileDescriptor(); fileDesc.setOriginalAbsoluteFilePath(bitStream.getSource()); fileDesc.setFilename(bitStream.getName()); fileDesc.setChecksum(bitStream.getChecksum()); fileDesc.setChecksumAlgorithm(bitStream.getChecksumAlgorithm()); fileDesc.setSize(bitStream.getSize()); BitstreamFormat format = bitStream.getFormat(); if (format != null) fileDesc.setMimeType(format.getMIMEType()); else fileDesc.setMimeType("application/octet-stream"); // The unique id must be get after the bitstream has been updated... fileDesc.setUniqueId(item.getHandle() + "/" + bitStream.getSequenceID()); descriptor.addContentFileDescriptor(fileDesc); } return descriptor; } private static FileSetDescriptor createFileSetAtLevel(Context ctx, Collection collection, String itemPath, FileSet fs, boolean privateFile) throws AuthorizeException, SQLException, IOException { // WorkspaceItem wi = WorkspaceItem.create(ctx, collection, false); // System.out.println("create wi "+fs.getContentFile(0).getName() +" : // "+ // (System.currentTimeMillis()-timeStart)+" ms"); // timeStart=System.currentTimeMillis(); // WorkflowManager.startWithoutNotify(ctx, wi); // System.out.println("workflow manager no notify // "+fs.getContentFile(0).getName() +" : "+ // (System.currentTimeMillis()-timeStart)+" ms"); // timeStart=System.currentTimeMillis(); // Item item = wi.getItem(); Item item = DSpaceFileManagerUtilities.createSimpleItem(ctx, collection); setItemPath(item, itemPath); FileSetDescriptor fsDescriptor = new FileSetDescriptor(); Bundle contentBundle = item.createBundle("ORIGINAL"); Bundle metaBundle = item.createBundle("META"); item.addBundle(contentBundle); item.addBundle(metaBundle); // HashMap bitStreamsPaths=new HashMap(); BufferedInputStream bis = null; for (File f : fs.getContentFiles()) { bis = new BufferedInputStream(new FileInputStream(f)); Bitstream bitStream = contentBundle.createBitstream(bis); bitStream.setName(f.getName()); bitStream.setSource(f.getAbsolutePath()); BitstreamFormat format = FormatIdentifier.guessFormat(ctx, bitStream); bitStream.setFormat(format); // bitStreamsPaths.put(bitStream, f.getAbsolutePath()); } for (File f : fs.getMetaFiles()) { bis = new BufferedInputStream(new FileInputStream(f)); Bitstream bitStream = metaBundle.createBitstream(bis); bitStream.setName(f.getName()); bitStream.setSource(f.getAbsolutePath()); BitstreamFormat format = FormatIdentifier.guessFormat(ctx, bitStream); bitStream.setFormat(format); // bitStreamsPaths.put(bitStream, f.getAbsolutePath()); } for (FileSetMetaData metaData : fs.getMetaInfo()) { item.addDC(metaData.getElement(), metaData.getQualifier(), metaData.getLang(), metaData .getValues()); fsDescriptor.addMetaInfo(metaData); } // item.update(); String itemHandle = DSpaceFileManagerUtilities.updateSimpleItem(ctx, collection, item); setItemPolicies(ctx, item, privateFile); indexContent(ctx, item); for (Bitstream bitStream : contentBundle.getBitstreams()) { FileDescriptor fileDesc = new FileDescriptor(); fileDesc.setOriginalAbsoluteFilePath(bitStream.getSource()); fileDesc.setFilename(bitStream.getName()); fileDesc.setChecksum(bitStream.getChecksum()); fileDesc.setChecksumAlgorithm(bitStream.getChecksumAlgorithm()); fileDesc.setSize(bitStream.getSize()); BitstreamFormat format = bitStream.getFormat(); if (format != null) fileDesc.setMimeType(format.getMIMEType()); else fileDesc.setMimeType("application/octet-stream"); // The unique id must be get after the bitstream has been updated... fileDesc.setUniqueId(itemHandle + "/" + bitStream.getSequenceID()); fsDescriptor.addContentFileDescriptor(fileDesc); setBitstreamPolicies(ctx, bitStream, privateFile); } for (Bitstream bitStream : metaBundle.getBitstreams()) { FileDescriptor fileDesc = new FileDescriptor(); fileDesc.setOriginalAbsoluteFilePath(bitStream.getSource()); fileDesc.setFilename(bitStream.getName()); fileDesc.setChecksum(bitStream.getChecksum()); fileDesc.setChecksumAlgorithm(bitStream.getChecksumAlgorithm()); fileDesc.setSize(bitStream.getSize()); BitstreamFormat format = bitStream.getFormat(); if (format != null) fileDesc.setMimeType(format.getMIMEType()); else fileDesc.setMimeType("application/octet-stream"); // The unique id must be get after the bitstream has been updated... fileDesc.setUniqueId(itemHandle + "/" + bitStream.getSequenceID()); fsDescriptor.addMetaFileDescriptors(fileDesc); setBitstreamPolicies(ctx, bitStream, privateFile); } return fsDescriptor; } private static void indexContent(Context ctx, DSpaceObject dSpaceObject) throws SQLException, IOException { DSIndexer.indexContent(ctx, dSpaceObject); } private static void unIndexContent(Context context, DSpaceObject dSpaceObject) throws SQLException, IOException { DSIndexer.unIndexContent(context, dSpaceObject); } private static void reIndexContent(Context context, DSpaceObject dSpaceObject) throws SQLException, IOException { DSIndexer.reIndexContent(context, dSpaceObject); } private static Bitstream resolveBitStream(Context ctx, String bitStreamIdentifier) throws DSpaceRemoteManagerException { Item theItemForTheBitStream = getItemForTheBitStream(ctx, bitStreamIdentifier); String bitStreamSequenceIdStr = bitStreamIdentifier .substring(bitStreamIdentifier.lastIndexOf('/') + 1); try { int bitstreamSequenceId = Integer.parseInt(bitStreamSequenceIdStr); return getBistreamFromItemByBitstreamSequenceId(theItemForTheBitStream, bitstreamSequenceId); } catch (Exception e) { throw new DSpaceRemoteManagerException("Unable to find bitStream for sequenceId=" + bitStreamSequenceIdStr + " in item " + theItemForTheBitStream.getHandle()); } } private static Item getItemForTheBitStream(Context ctx, String bitStreamIdentifier) throws DSpaceRemoteManagerException { if (bitStreamIdentifier == null || bitStreamIdentifier.lastIndexOf('/') == -1) throw new DSpaceRemoteManagerException("bitStreamIdentifier is not correctly formated : " + bitStreamIdentifier); String itemHandle = bitStreamIdentifier.substring(0, bitStreamIdentifier.lastIndexOf('/')); Item theItemForTheBitStream; try { theItemForTheBitStream = (Item) HandleManager.resolveToObject(ctx, itemHandle); } catch (SQLException e) { throw new DSpaceRemoteManagerException("Could not find Item for handle " + itemHandle + " for bitStream " + bitStreamIdentifier, e); } if (theItemForTheBitStream == null) throw new DSpaceRemoteManagerException("Could not find Item for handle " + itemHandle + " for bitStream " + bitStreamIdentifier); return theItemForTheBitStream; } public static FileSetDescriptor listFromRoot(Context ctx, FileSetDescriptor fsDescriptor) throws DSpaceRemoteManagerException { FileSetDescriptor descriptor = new FileSetDescriptor(); // ItemIterator itemIterator=collection.getItems(); FileDescriptor firstFileDescriptor = fsDescriptor.getContentFileDescriptor(0); // descriptor.addContentFileDescriptor(firstFileDescriptor); String bitStreamIdentifier = firstFileDescriptor.getUniqueId(); Item theItemForTheFirstBitStream = getItemForTheBitStream(ctx, bitStreamIdentifier); fillBasicFileSetDescriptor(theItemForTheFirstBitStream, descriptor); String firstBitStreamItemPath = getItemPath(theItemForTheFirstBitStream); if (firstBitStreamItemPath == null) { LogFactory.getLog(DSpaceRemoteManager.class).debug( "Could not find item path for item " + theItemForTheFirstBitStream.getHandle()); // return just a simple file set descriptor as this file was not // added by // us, so there is not path info } else { // we have path info so it was added by us... look for childs also String basePath = firstBitStreamItemPath + "/"; Collection itemsCollection; try { itemsCollection = theItemForTheFirstBitStream.getOwningCollection(); ItemIterator itemsIter = itemsCollection.getItems(); while (itemsIter.hasNext()) { Item currentItem = itemsIter.next(); String currentItemPath = getItemPath(currentItem); if (currentItemPath != null && currentItemPath.startsWith(basePath)) { String relativeCurrentItemPath = currentItemPath.substring(basePath.length()); FileSetDescriptor currentDescriptor = new FileSetDescriptor(); fillBasicFileSetDescriptor(currentItem, currentDescriptor); addFileSetDescriptorAtPathLevel(descriptor, currentDescriptor, getPathComponentCount(relativeCurrentItemPath)); } } } catch (SQLException e) { throw new DSpaceRemoteManagerException("unable to read item or collection from database"); } } return descriptor; } public static FileSetDescriptor getRootDescriptor(Context ctx, FileSetDescriptor fsDescriptor) throws DSpaceRemoteManagerException { FileSetDescriptor descriptor = new FileSetDescriptor(); // ItemIterator itemIterator=collection.getItems(); FileDescriptor firstFileDescriptor = fsDescriptor.getContentFileDescriptor(0); String bitStreamIdentifier = firstFileDescriptor.getUniqueId(); Item theItemForTheFirstBitStream = getItemForTheBitStream(ctx, bitStreamIdentifier); String firstBitStreamItemPath = getItemPath(theItemForTheFirstBitStream); if (firstBitStreamItemPath == null) { LogFactory.getLog(DSpaceRemoteManager.class).debug( "Could not find item path for item " + theItemForTheFirstBitStream.getHandle()); // create a simple file set descriptor as this file was not added by // us, so there is not path info fillBasicFileSetDescriptor(theItemForTheFirstBitStream, descriptor); } else { String internalItemPath = firstBitStreamItemPath; String basePath = internalItemPath; int firstSlashPos = basePath.indexOf("/"); int nextSlashPos = basePath.indexOf("/", firstSlashPos + 1); if (nextSlashPos > 0) basePath = basePath.substring(0, nextSlashPos); Collection itemsCollection; try { itemsCollection = theItemForTheFirstBitStream.getOwningCollection(); ItemIterator itemsIter = itemsCollection.getItems(); while (itemsIter.hasNext()) { Item currentItem = itemsIter.next(); String currentItemPath = getItemPath(currentItem); if (currentItemPath != null && currentItemPath.startsWith(basePath)) { String relativeCurrentItemPath = currentItemPath.substring(basePath.length()); FileSetDescriptor currentDescriptor = new FileSetDescriptor(); fillBasicFileSetDescriptor(currentItem, currentDescriptor); addFileSetDescriptorAtPathLevel(descriptor, currentDescriptor, getPathComponentCount(relativeCurrentItemPath)); } } } catch (SQLException e) { throw new DSpaceRemoteManagerException("unable to read item or collection from database"); } } return descriptor; } private static void addFileSetDescriptorAtPathLevel(FileSetDescriptor descriptor, FileSetDescriptor currentDescriptor, int pathComponentCount) { int decrescentCount = pathComponentCount; FileSetDescriptor parentFileSetDescriptor = descriptor; while (decrescentCount > 0) { --decrescentCount; FileSetDescriptor[] childs = parentFileSetDescriptor.getChildSets().toArray( new FileSetDescriptor[0]); if (decrescentCount > 0 && (childs != null && childs.length > 0)) parentFileSetDescriptor = childs[0]; else {// it is the last path component or there are no child sets // defined, so we have to create an empty // one FileSetDescriptor childSetDescriptor = new FileSetDescriptor(); parentFileSetDescriptor.addChildSet(childSetDescriptor); parentFileSetDescriptor = childSetDescriptor; } } // now change the values in the parentFileSetDescriptor parentFileSetDescriptor.setContentFilesDescriptors(currentDescriptor.getContentFilesDescriptors()); parentFileSetDescriptor.setMetaFilesDescriptors(currentDescriptor.getMetaFilesDescriptors()); parentFileSetDescriptor.setMetaInfo(currentDescriptor.getMetaInfo()); } private static void fillBasicFileSetDescriptor(Item currentItem, FileSetDescriptor currentDescriptor) { // Add the item metadata to the descriptor DCValue[] dublinCoreMeta = currentItem.getDC(Item.ANY, Item.ANY, Item.ANY); if (dublinCoreMeta != null) for (DCValue currentDC : dublinCoreMeta) { currentDescriptor.addMetaInfo(new FileSetMetaData(currentDC.element, currentDC.qualifier, currentDC.language, currentDC.value)); } // fetch the content and metaBundles arrays Bundle[] contentBundles = currentItem.getBundles("ORIGINAL"); Bundle[] metaBundles = currentItem.getBundles("META"); if (contentBundles != null && contentBundles.length > 0) { for (Bundle contentBundle : contentBundles) { currentDescriptor.addContentFileDescriptor(createFileDescriptorsForBundle(currentItem, contentBundle)); } } if (metaBundles != null && metaBundles.length > 0) { for (Bundle metaBundle : metaBundles) { currentDescriptor.addMetaFileDescriptors(createFileDescriptorsForBundle(currentItem, metaBundle)); } } } private static java.util.Collection createFileDescriptorsForBundle(Item i, Bundle b) { if (b.getBitstreams() == null || b.getBitstreams().length == 0) return new ArrayList(0); ArrayList fDescriptors = new ArrayList(b.getBitstreams().length); for (Bitstream bitStream : b.getBitstreams()) { FileDescriptor fDescriptor = new FileDescriptor(); fDescriptor.setChecksum(bitStream.getChecksum()); fDescriptor.setChecksumAlgorithm(bitStream.getChecksumAlgorithm()); fDescriptor.setFilename(bitStream.getName()); fDescriptor.setOriginalAbsoluteFilePath(bitStream.getSource()); fDescriptor.setSize(bitStream.getSize()); fDescriptor.setUniqueId(i.getHandle() + "/" + bitStream.getSequenceID()); fDescriptors.add(fDescriptor); } return fDescriptors; } private static int getPathComponentCount(String pathComponent) { int countComponents = 0; String pathTemp = pathComponent; while (pathTemp.indexOf('/') != -1) { pathTemp = pathTemp.substring(pathTemp.indexOf('/') + 1); countComponents++; } return countComponents; } private static void recurseObjectTree(Object rootOfTree, String methodName, Class[] additionalArgTypes, Object[] additionalArgs) throws DSpaceRemoteManagerException, AuthorizeException, SQLException, IOException { try { TreeUtilities.createTreeUtilities().recurseTreeCallMethod(rootOfTree, "getChildSets", getInstance(), methodName, additionalArgTypes, additionalArgs); } catch (TreeRecurseException e) { throw new DSpaceRemoteManagerException("Executing " + methodName + " error: " + e.getMessage(), e); } } @SuppressWarnings("unchecked") public static FileSetQueryResults searchItems(Context context, FilesetMetadataQuery query, VirtualPath path) throws DSpaceRemoteManagerException { boolean rollback = false; try { DCQueryParser parsedQuery = new DCQueryParser(); parsedQuery.setQuery(parsedQuery.buildQuery(query) + "-(NOT (type:PROJECT_SUBMISSION))"); parsedQuery.setStart(query.getStart()); parsedQuery.setPageSize(query.getPageSize()); FileSetQueryResults queryResults = new FileSetQueryResults(); Community community; org.dspace.search.QueryResults results; if (path == null) { results = DSQuery.doQuery(context, parsedQuery); } else { community = getCommunity(context, path); if (community != null) { results = DSQuery.doQuery(context, parsedQuery, community); } else { results = createEmptyResult(); } } queryResults.setStart(query.getStart()); queryResults.setPageSize(results.getPageSize()); queryResults.setHitsCount(results.getHitCount()); List possibleItemHandles = results.getHitHandles(); List handleTypes = results.getHitTypes(); for (int j = 0; j < possibleItemHandles.size(); j++) { if (handleTypes.get(j).equals(Constants.ITEM)) { String handleItem = possibleItemHandles.get(j); FileSetDescriptor descriptorResult = new FileSetDescriptor(); Item item = (Item) HandleManager.resolveToObject(context, handleItem); if (item != null) { fillBasicFileSetDescriptor(item, descriptorResult); queryResults.getResults().add(descriptorResult); } } } return queryResults; } catch (Exception e) { rollback = true; throw new DSpaceRemoteManagerException(e.getMessage()); } finally { if (rollback == true) { context.abort(); } else { try { context.complete(); } catch (SQLException e) { throw new DSpaceRemoteManagerException(e.getMessage()); } } } } private static org.dspace.search.QueryResults createEmptyResult() { org.dspace.search.QueryResults results; results = new org.dspace.search.QueryResults(); List hitHandles = new ArrayList(); List hitTypes = new ArrayList(); results.setHitHandles(hitHandles); results.setHitTypes(hitTypes); results.setStart(0); results.setPageSize(0); return results; } }