@Override public int perform(DSpaceObject dso) throws IOException { status = Curator.CURATE_SKIP; logDebugMessage("The target dso is " + dso.getName()); if (dso instanceof Item) { status = Curator.CURATE_SUCCESS; Item item = (Item) dso; try { openSession(); } catch (IOException ioE) { // no point going further - set result and error out closeSession(); setResult(CONNECT_FAIL_MESSAGE); return Curator.CURATE_ERROR; } try { Bundle bundle = item.getBundles("ORIGINAL")[0]; results = new ArrayList<String>(); for (Bitstream bitstream : bundle.getBitstreams()) { InputStream inputstream = bitstream.retrieve(); logDebugMessage("Scanning " + bitstream.getName() + " . . . "); int bstatus = scan(bitstream, inputstream, getItemHandle(item)); inputstream.close(); if (bstatus == Curator.CURATE_ERROR) { // no point going further - set result and error out setResult(SCAN_FAIL_MESSAGE); status = bstatus; break; } if (failfast && bstatus == Curator.CURATE_FAIL) { status = bstatus; break; } else if (bstatus == Curator.CURATE_FAIL && status == Curator.CURATE_SUCCESS) { status = bstatus; } } } catch (AuthorizeException authE) { throw new IOException(authE.getMessage(), authE); } catch (SQLException sqlE) { throw new IOException(sqlE.getMessage(), sqlE); } finally { closeSession(); } if (status != Curator.CURATE_ERROR) { formatResults(item); } } return status; }
@GET @Path("/{bitstream_id}/retrieve") public javax.ws.rs.core.Response getFile( @PathParam("bitstream_id") final Integer bitstream_id, @QueryParam("userIP") String user_ip, @QueryParam("userAgent") String user_agent, @QueryParam("xforwarderfor") String xforwarderfor, @Context HttpHeaders headers, @Context HttpServletRequest request) { org.dspace.core.Context context = null; try { context = new org.dspace.core.Context(); org.dspace.content.Bitstream bitstream = org.dspace.content.Bitstream.find(context, bitstream_id); if (AuthorizeManager.authorizeActionBoolean( context, bitstream, org.dspace.core.Constants.READ)) { if (writeStatistics) { writeStats(context, bitstream_id, user_ip, user_agent, xforwarderfor, headers, request); } return Response.ok(bitstream.retrieve()).type(bitstream.getFormat().getMIMEType()).build(); } else { throw new WebApplicationException(Response.Status.UNAUTHORIZED); } } catch (IOException e) { log.error(e.getMessage()); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (SQLException e) { log.error(e.getMessage()); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (AuthorizeException e) { log.error(e.getMessage()); throw new WebApplicationException(Response.Status.UNAUTHORIZED); } finally { if (context != null) { try { context.complete(); } catch (SQLException e) { log.error(e.getMessage() + " occurred while trying to close"); } } } }
/** Write out a METS manifest. Mostly lifted from Rob Tansley's METS exporter. */ private void writeManifest(Context context, Item item, PackageParameters params, OutputStream out) throws PackageValidationException, CrosswalkException, AuthorizeException, SQLException, IOException { try { // Create the METS file Mets mets = new Mets(); // Top-level stuff mets.setID(gensym("mets")); mets.setOBJID("hdl:" + item.getHandle()); mets.setLABEL("DSpace Item"); mets.setPROFILE(getProfile()); // MetsHdr MetsHdr metsHdr = new MetsHdr(); metsHdr.setCREATEDATE(new Date()); // FIXME: CREATEDATE is now: // maybe should be item create // date? // Agent Agent agent = new Agent(); agent.setROLE(Role.CUSTODIAN); agent.setTYPE(Type.ORGANIZATION); Name name = new Name(); name.getContent().add(new PCData(ConfigurationManager.getProperty("dspace.name"))); agent.getContent().add(name); metsHdr.getContent().add(agent); mets.getContent().add(metsHdr); // add DMD sections // Each type element MAY be either just a MODS-and-crosswalk name, OR // a combination "MODS-name:crosswalk-name" (e.g. "DC:qDC"). String dmdTypes[] = getDmdTypes(params); // record of ID of each dmdsec to make DMDID in structmap. String dmdGroup = gensym("dmd_group"); String dmdId[] = new String[dmdTypes.length]; for (int i = 0; i < dmdTypes.length; ++i) { dmdId[i] = gensym("dmd"); XmlData xmlData = new XmlData(); String xwalkName, metsName; String parts[] = dmdTypes[i].split(":", 2); if (parts.length > 1) { metsName = parts[0]; xwalkName = parts[1]; } else xwalkName = metsName = dmdTypes[i]; DisseminationCrosswalk xwalk = (DisseminationCrosswalk) PluginManager.getNamedPlugin(DisseminationCrosswalk.class, xwalkName); if (xwalk == null) throw new PackageValidationException("Cannot find " + dmdTypes[i] + " crosswalk plugin!"); else crosswalkToMets(xwalk, item, xmlData); DmdSec dmdSec = new DmdSec(); dmdSec.setID(dmdId[i]); dmdSec.setGROUPID(dmdGroup); MdWrap mdWrap = new MdWrap(); setMdType(mdWrap, metsName); mdWrap.getContent().add(xmlData); dmdSec.getContent().add(mdWrap); mets.getContent().add(dmdSec); } // Only add license AMD section if there are any licenses. // Catch authorization failures accessing license bitstreams // only if we are skipping unauthorized bitstreams. String licenseID = null; try { AmdSec amdSec = new AmdSec(); addRightsMd(context, item, amdSec); if (amdSec.getContent().size() > 0) { licenseID = gensym("license"); amdSec.setID(licenseID); mets.getContent().add(amdSec); } } catch (AuthorizeException e) { String unauth = (params == null) ? null : params.getProperty("unauthorized"); if (!(unauth != null && unauth.equalsIgnoreCase("skip"))) throw e; else log.warn("Skipping license metadata because of access failure: " + e.toString()); } // FIXME: History data???? Nooooo!!!! // fileSec - all non-metadata bundles go into fileGrp, // and each bitstream therein into a file. // Create the bitstream-level techMd and div's for structmap // at the same time so we can connec the IDREFs to IDs. FileSec fileSec = new FileSec(); String techMdType = getTechMdType(params); String parts[] = techMdType.split(":", 2); String xwalkName, metsName; if (parts.length > 1) { metsName = parts[0]; xwalkName = parts[1]; } else xwalkName = metsName = techMdType; DisseminationCrosswalk xwalk = (DisseminationCrosswalk) PluginManager.getNamedPlugin(DisseminationCrosswalk.class, xwalkName); if (xwalk == null) throw new PackageValidationException("Cannot find " + xwalkName + " crosswalk plugin!"); // log the primary bitstream for structmap String primaryBitstreamFileID = null; // accumulate content DIV items to put in structMap later. List contentDivs = new ArrayList(); // how to handle unauthorized bundle/bitstream: String unauth = (params == null) ? null : params.getProperty("unauthorized"); Bundle[] bundles = item.getBundles(); for (int i = 0; i < bundles.length; i++) { if (PackageUtils.isMetaInfoBundle(bundles[i])) continue; // unauthorized bundle? // NOTE: This must match the logic in disseminate() if (!AuthorizeManager.authorizeActionBoolean(context, bundles[i], Constants.READ)) { if (unauth != null && (unauth.equalsIgnoreCase("skip"))) continue; else throw new AuthorizeException( "Not authorized to read Bundle named \"" + bundles[i].getName() + "\""); } Bitstream[] bitstreams = bundles[i].getBitstreams(); // Create a fileGrp FileGrp fileGrp = new FileGrp(); // Bundle name for USE attribute String bName = bundles[i].getName(); if ((bName != null) && !bName.equals("")) fileGrp.setUSE(bundleToFileGrp(bName)); // watch for primary bitstream int primaryBitstreamID = -1; boolean isContentBundle = false; if ((bName != null) && bName.equals("ORIGINAL")) { isContentBundle = true; primaryBitstreamID = bundles[i].getPrimaryBitstreamID(); } for (int bits = 0; bits < bitstreams.length; bits++) { // Check for authorization. Handle unauthorized // bitstreams to match the logic in disseminate(), // i.e. "unauth=zero" means include a 0-length bitstream, // "unauth=skip" means to ignore it (and exclude from // manifest). boolean auth = AuthorizeManager.authorizeActionBoolean(context, bitstreams[bits], Constants.READ); if (!auth) { if (unauth != null && unauth.equalsIgnoreCase("skip")) continue; else if (!(unauth != null && unauth.equalsIgnoreCase("zero"))) throw new AuthorizeException( "Not authorized to read Bitstream, SID=" + String.valueOf(bitstreams[bits].getSequenceID())); } String sid = String.valueOf(bitstreams[bits].getSequenceID()); edu.harvard.hul.ois.mets.File file = new edu.harvard.hul.ois.mets.File(); String xmlIDstart = "bitstream_"; String fileID = xmlIDstart + sid; file.setID(fileID); // log primary bitstream for later (structMap) if (bitstreams[bits].getID() == primaryBitstreamID) primaryBitstreamFileID = fileID; // if this is content, add to structmap too: if (isContentBundle) { Div div = new Div(); div.setID(gensym("div")); div.setTYPE("DSpace Content Bitstream"); Fptr fptr = new Fptr(); fptr.setFILEID(fileID); div.getContent().add(fptr); contentDivs.add(div); } file.setSEQ(bitstreams[bits].getSequenceID()); String groupID = "GROUP_" + xmlIDstart + sid; /* * If we're in THUMBNAIL or TEXT bundles, the bitstream is * extracted text or a thumbnail, so we use the name to work * out which bitstream to be in the same group as */ if ((bundles[i].getName() != null) && (bundles[i].getName().equals("THUMBNAIL") || bundles[i].getName().startsWith("TEXT"))) { // Try and find the original bitstream, and chuck the // derived bitstream in the same group Bitstream original = findOriginalBitstream(item, bitstreams[bits]); if (original != null) { groupID = "GROUP_" + xmlIDstart + original.getSequenceID(); } } file.setGROUPID(groupID); file.setMIMETYPE(bitstreams[bits].getFormat().getMIMEType()); // FIXME: CREATED: no date file.setSIZE(auth ? bitstreams[bits].getSize() : 0); // translate checksum and type to METS, if available. String csType = bitstreams[bits].getChecksumAlgorithm(); String cs = bitstreams[bits].getChecksum(); if (auth && cs != null && csType != null) { try { file.setCHECKSUMTYPE(Checksumtype.parse(csType)); file.setCHECKSUM(cs); } catch (MetsException e) { log.warn("Cannot set bitstream checksum type=" + csType + " in METS."); } } // FLocat: filename is MD5 checksum FLocat flocat = new FLocat(); flocat.setLOCTYPE(Loctype.URL); flocat.setXlinkHref(makeBitstreamName(bitstreams[bits])); // Make bitstream techMD metadata, add to file. String techID = "techMd_for_bitstream_" + bitstreams[bits].getSequenceID(); AmdSec fAmdSec = new AmdSec(); fAmdSec.setID(techID); TechMD techMd = new TechMD(); techMd.setID(gensym("tech")); MdWrap mdWrap = new MdWrap(); setMdType(mdWrap, metsName); XmlData xmlData = new XmlData(); mdWrap.getContent().add(xmlData); techMd.getContent().add(mdWrap); fAmdSec.getContent().add(techMd); mets.getContent().add(fAmdSec); crosswalkToMets(xwalk, bitstreams[bits], xmlData); file.setADMID(techID); // Add FLocat to File, and File to FileGrp file.getContent().add(flocat); fileGrp.getContent().add(file); } // Add fileGrp to fileSec fileSec.getContent().add(fileGrp); } // Add fileSec to document mets.getContent().add(fileSec); // Create simple structMap: initial div represents the Item, // and user-visible content bitstreams are in its child divs. StringBuffer dmdIds = new StringBuffer(); for (int i = 0; i < dmdId.length; ++i) dmdIds.append(" " + dmdId[i]); StructMap structMap = new StructMap(); structMap.setID(gensym("struct")); structMap.setTYPE("LOGICAL"); structMap.setLABEL("DSpace"); Div div0 = new Div(); div0.setID(gensym("div")); div0.setTYPE("DSpace Item"); div0.setDMDID(dmdIds.substring(1)); if (licenseID != null) div0.setADMID(licenseID); // if there is a primary bitstream, add FPTR to it. if (primaryBitstreamFileID != null) { Fptr fptr = new Fptr(); fptr.setFILEID(primaryBitstreamFileID); div0.getContent().add(fptr); } // add DIV for each content bitstream div0.getContent().addAll(contentDivs); structMap.getContent().add(div0); // Does subclass have something to add to structMap? addStructMap(context, item, params, mets); mets.getContent().add(structMap); mets.validate(new MetsValidator()); mets.write(new MetsWriter(out)); } catch (MetsException e) { // We don't pass up a MetsException, so callers don't need to // know the details of the METS toolkit // e.printStackTrace(); throw new PackageValidationException(e); } }
public static void main(String[] argv) throws Exception { // create an options object and populate it CommandLineParser parser = new PosixParser(); Options options = new Options(); options.addOption("s", "set", false, "set a parent/child relationship"); options.addOption("r", "remove", false, "remove a parent/child relationship"); options.addOption("p", "parent", true, "parent community (handle or database ID)"); options.addOption("c", "child", true, "child community (handle or databaseID)"); options.addOption("h", "help", false, "help"); CommandLine line = parser.parse(options, argv); String command = null; // set or remove String parentID = null; String childID = null; if (line.hasOption('h')) { HelpFormatter myhelp = new HelpFormatter(); myhelp.printHelp("CommunityFiliator\n", options); System.out.println("\nestablish a relationship: CommunityFiliator -s -p parentID -c childID"); System.out.println("remove a relationship: CommunityFiliator -r -p parentID -c childID"); System.exit(0); } if (line.hasOption('s')) { command = "set"; } if (line.hasOption('r')) { command = "remove"; } if (line.hasOption('p')) // parent { parentID = line.getOptionValue('p'); } if (line.hasOption('c')) // child { childID = line.getOptionValue('c'); } // now validate // must have a command set if (command == null) { System.out.println( "Error - must run with either set or remove (run with -h flag for details)"); System.exit(1); } if (command.equals("set") || command.equals("remove")) { if (parentID == null) { System.out.println("Error - a parentID must be specified (run with -h flag for details)"); System.exit(1); } if (childID == null) { System.out.println("Error - a childID must be specified (run with -h flag for details)"); System.exit(1); } } CommunityFiliator filiator = new CommunityFiliator(); Context c = new Context(); // ve are superuser! c.setIgnoreAuthorization(true); try { // validate and resolve the parent and child IDs into commmunities Community parent = filiator.resolveCommunity(c, parentID); Community child = filiator.resolveCommunity(c, childID); if (parent == null) { System.out.println("Error, parent community cannot be found: " + parentID); System.exit(1); } if (child == null) { System.out.println("Error, child community cannot be found: " + childID); System.exit(1); } if (command.equals("set")) { filiator.filiate(c, parent, child); } else { filiator.defiliate(c, parent, child); } } catch (SQLException sqlE) { System.out.println("Error - SQL exception: " + sqlE.toString()); } catch (AuthorizeException authE) { System.out.println("Error - Authorize exception: " + authE.toString()); } catch (IOException ioE) { System.out.println("Error - IO exception: " + ioE.toString()); } }
/** * Return instance of collection with passed id. You can add more properties through expand * parameter. * * @param expand String in which is what you want to add to returned instance of collection. * Options are: "all", "parentCommunityList", "parentCommunity", "items", "license" and * "logo". If you want to use multiple options, it must be separated by commas. * @param limit Limit value for items in list in collection. Default value is 100. * @param offset Offset of start index in list of items of collection. Default value is 0. * @param filters Comma separated list of Item Filters to use to evaluate against the items in a * collection * @param query_field List of metadata fields to evaluate in a metadata query. Each list value is * used in conjunction with a query_op and query_field. * @param query_op List of metadata operators to use in a metadata query. Each list value is used * in conjunction with a query_field and query_field. * @param query_val List of metadata values to evaluate in a metadata query. Each list value is * used in conjunction with a query_value and query_op. * @param collSel List of collections to query. * @param headers If you want to access to collection under logged user into context. In headers * must be set header "rest-dspace-token" with passed token from login method. * @return Return instance of collection. It can also return status code NOT_FOUND(404) if id of * collection is incorrect or status code UNATHORIZED(401) if user has no permission to read * collection. * @throws WebApplicationException It is thrown when was problem with database reading * (SQLException) or problem with creating context(ContextException). It is thrown by * NOT_FOUND and UNATHORIZED status codes, too. */ @GET @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public org.dspace.rest.common.ItemFilter getItemQuery( @QueryParam("expand") String expand, @QueryParam("limit") @DefaultValue("100") Integer limit, @QueryParam("offset") @DefaultValue("0") Integer offset, @QueryParam("userIP") String user_ip, @QueryParam("userAgent") String user_agent, @QueryParam("xforwarderfor") String xforwarderfor, @QueryParam("filters") @DefaultValue("is_item,all_filters") String filters, @QueryParam("query_field[]") @DefaultValue("dc.title") List<String> query_field, @QueryParam("query_op[]") @DefaultValue("exists") List<String> query_op, @QueryParam("query_val[]") @DefaultValue("") List<String> query_val, @QueryParam("collSel[]") @DefaultValue("") List<String> collSel, @Context HttpHeaders headers, @Context HttpServletRequest request) { org.dspace.core.Context context = null; ItemFilterSet itemFilterSet = new ItemFilterSet(filters, true); ItemFilter result = itemFilterSet.getAllFiltersFilter(); try { context = createContext(getUser(headers)); if (!configurationService.getBooleanProperty("rest.reporting-authenticate", true)) { context.turnOffAuthorisationSystem(); } int index = Math.min(query_field.size(), Math.min(query_op.size(), query_val.size())); List<ItemFilterQuery> itemFilterQueries = new ArrayList<ItemFilterQuery>(); for (int i = 0; i < index; i++) { itemFilterQueries.add( new ItemFilterQuery(query_field.get(i), query_op.get(i), query_val.get(i))); } String regexClause = configurationService.getProperty("rest.regex-clause"); if (regexClause == null) { regexClause = ""; } List<UUID> uuids = getUuidsFromStrings(collSel); List<List<MetadataField>> listFieldList = getMetadataFieldsList(context, query_field); Iterator<org.dspace.content.Item> childItems = itemService.findByMetadataQuery( context, listFieldList, query_op, query_val, uuids, regexClause, offset, limit); int count = itemFilterSet.processSaveItems(context, childItems, true, expand); writeStats( siteService.findSite(context), UsageEvent.Action.VIEW, user_ip, user_agent, xforwarderfor, headers, request, context); result.annotateQuery(query_field, query_op, query_val); result.setUnfilteredItemCount(count); context.complete(); } catch (IOException e) { processException(e.getMessage(), context); } catch (SQLException e) { processException(e.getMessage(), context); } catch (AuthorizeException e) { processException(e.getMessage(), context); } catch (ContextException e) { processException("Unauthorized filtered item query. " + e.getMessage(), context); } finally { processFinally(context); } return result; }
protected void dspaceDFS(DSpaceObject dso, Callback callback, boolean check, boolean reset) throws SQLException { if (dso.getType() != Constants.SITE && dso.getType() != Constants.COMMUNITY && dso.getType() != Constants.COLLECTION && dso.getType() != Constants.ITEM) { throw new IllegalArgumentException( contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso) + " is currently not supported as independent entity."); } if (reset) { this.processed.clear(); } if (isProcessed(dso)) { log.debug( "Skipping processing of " + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso) + " " + dso.getID() + " (handle " + dso.getHandle() + "), already processed."); return; } markProcessed(dso); // this is useful to debug depth first search, but it is really noisy. // log.debug("Procesing " + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso) + // " " + dso.getID() + ":" + dso.getHandle() + "."); // if this method is used for conversion we should check if we have the // permissions to read a DSO before converting all of it decendents // (e.g. check read permission on a community before converting all of // its subcommunties and collections). // just skip items with missing permissions and report them. if (check) { try { RDFUtil.isPublic(context, dso); } catch (ItemNotArchivedException ex) { if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex); report( "Skipping processing of Item " + dso.getID() + " (handle " + dso.getHandle() + "): Item is not " + "archived."); return; } catch (ItemWithdrawnException ex) { if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex); report( "Skipping processing of Item " + dso.getID() + " (handle " + dso.getHandle() + "): Item is " + "withdrawn."); return; } catch (ItemNotDiscoverableException ex) { if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex); report( "Skipping processing of Item " + dso.getID() + " (handle " + dso.getHandle() + "): Item is not " + "discoverable."); return; } catch (AuthorizeException ex) { report( "Skipping processing of " + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso) + " " + dso.getID() + " (handle " + dso.getHandle() + ")" + ", not authorized: " + ex.getMessage()); return; } } if (dso instanceof Site) { List<Community> communities = communityService.findAllTop(context); for (Community community : communities) { this.dspaceDFS(community, callback, check, false); } } if (dso instanceof Community) { List<Community> subcommunities = ((Community) dso).getSubcommunities(); for (Community sub : subcommunities) { this.dspaceDFS(sub, callback, check, false); } List<Collection> collections = ((Community) dso).getCollections(); for (Collection collection : collections) { this.dspaceDFS(collection, callback, check, false); } } if (dso instanceof Collection) { Iterator<Item> items = itemService.findAllByCollection(context, (Collection) dso); while (items.hasNext()) { Item item = items.next(); this.dspaceDFS(item, callback, check, false); } } // Currently Bundles and Bitsreams aren't supported as independent entities. // They should be converted as part of an item. So we do not need to make // the recursive call for them. An item itself will be converted as part // of the callback call below. // The following code is left here for the day, we decide to also convert // bundles and/or bitstreams. // // if (dso instanceof Item) // { // Bundle[] bundles = ((Item) dso).getBundles(); // for (Bundle bundle : bundles) // { // this.dspaceDFS(bundle, callback, check, false); // } // } // // if (dso instanceof Bundle) // { // Bitstream[] bistreams = ((Bundle) dso).getBitstreams(); // for (Bitstream bitstream : bistreams) // { // this.dspaceDFS(bitstream, callback, check, false); // } // } callback.callback(dso); report( "Processed " + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso) + " " + dso.getID() + " (handle " + dso.getHandle() + ")."); }