mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-13 13:03:11 +00:00
DS-2175 Citation PDF initial implementation
This commit is contained in:
@@ -618,6 +618,19 @@
|
|||||||
<groupId>com.google.code.findbugs</groupId>
|
<groupId>com.google.code.findbugs</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Needed for CitationPage CurationTask -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itextpdf</artifactId>
|
||||||
|
<version>5.1.2</version>
|
||||||
|
<type>jar</type>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf.tool</groupId>
|
||||||
|
<artifactId>xmlworker</artifactId>
|
||||||
|
<version>1.1.0</version>
|
||||||
|
<type>jar</type>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
232
dspace-api/src/main/java/org/dspace/curate/CitationPage.java
Normal file
232
dspace-api/src/main/java/org/dspace/curate/CitationPage.java
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.curate;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.*;
|
||||||
|
import org.dspace.disseminate.CitationDocument;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CitationPage
|
||||||
|
*
|
||||||
|
* This task is used to generate a cover page with citation information for text
|
||||||
|
* documents and then to add that cover page to a PDF version of the document
|
||||||
|
* replacing the originally uploaded document form the user's perspective.
|
||||||
|
*
|
||||||
|
* @author Ryan McGowan
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Distributive
|
||||||
|
@Mutative
|
||||||
|
public class CitationPage extends AbstractCurationTask {
|
||||||
|
/**
|
||||||
|
* Class Logger
|
||||||
|
*/
|
||||||
|
private static Logger log = Logger.getLogger(CitationPage.class);
|
||||||
|
|
||||||
|
private int status = Curator.CURATE_UNSET;
|
||||||
|
private String result = null;
|
||||||
|
/**
|
||||||
|
* A StringBuilder to handle result string building process.
|
||||||
|
*/
|
||||||
|
private StringBuilder resBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name to give the bundle we add the cited pages to.
|
||||||
|
*/
|
||||||
|
private static final String DISPLAY_BUNDLE_NAME = "DISPLAY";
|
||||||
|
/**
|
||||||
|
* The name of the bundle to move source documents into after they have been
|
||||||
|
* cited.
|
||||||
|
*/
|
||||||
|
private static final String PRESERVATION_BUNDLE_NAME = "PRESERVATION";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see CurationTask#perform(DSpaceObject)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int perform(DSpaceObject dso) throws IOException {
|
||||||
|
|
||||||
|
// Deal with status and result as well as call distribute.
|
||||||
|
this.resBuilder = new StringBuilder();
|
||||||
|
this.distribute(dso);
|
||||||
|
this.result = this.resBuilder.toString();
|
||||||
|
this.setResult(this.result);
|
||||||
|
this.report(this.result);
|
||||||
|
|
||||||
|
return this.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see AbstractCurationTask#performItem(Item)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void performItem(Item item) throws SQLException {
|
||||||
|
//Determine if the DISPLAY bundle exits. If not, create it.
|
||||||
|
Bundle[] dBundles = item.getBundles(CitationPage.DISPLAY_BUNDLE_NAME);
|
||||||
|
Bundle dBundle = null;
|
||||||
|
if (dBundles == null || dBundles.length == 0) {
|
||||||
|
try {
|
||||||
|
dBundle = item.createBundle(CitationPage.DISPLAY_BUNDLE_NAME);
|
||||||
|
} catch (AuthorizeException e) {
|
||||||
|
log.error("User not authroized to create bundle on item \""
|
||||||
|
+ item.getName() + "\": " + e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dBundle = dBundles[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create a map of the bitstreams in the displayBundle. This is used to
|
||||||
|
//check if the bundle being cited is already in the display bundle.
|
||||||
|
Map<String,Bitstream> displayMap = new HashMap<String,Bitstream>();
|
||||||
|
for (Bitstream bs : dBundle.getBitstreams()) {
|
||||||
|
displayMap.put(bs.getName(), bs);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Determine if the preservation bundle exists and add it if we need to.
|
||||||
|
//Also, set up bundles so it contains all ORIGINAL and PRESERVATION
|
||||||
|
//bitstreams.
|
||||||
|
Bundle[] pBundles = item.getBundles(CitationPage.PRESERVATION_BUNDLE_NAME);
|
||||||
|
Bundle pBundle = null;
|
||||||
|
Bundle[] bundles = null;
|
||||||
|
if (pBundles != null && pBundles.length > 0) {
|
||||||
|
pBundle = pBundles[0];
|
||||||
|
bundles = (Bundle[]) ArrayUtils.addAll(item.getBundles("ORIGINAL"), pBundles);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
pBundle = item.createBundle(CitationPage.PRESERVATION_BUNDLE_NAME);
|
||||||
|
} catch (AuthorizeException e) {
|
||||||
|
log.error("User not authroized to create bundle on item \""
|
||||||
|
+ item.getName() + "\": " + e.getMessage());
|
||||||
|
}
|
||||||
|
bundles = item.getBundles("ORIGINAL");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start looping through our bundles. Anything that is citable in these
|
||||||
|
//bundles will be cited.
|
||||||
|
for (Bundle bundle : bundles) {
|
||||||
|
Bitstream[] bitstreams = bundle.getBitstreams();
|
||||||
|
|
||||||
|
// Loop through each file and generate a cover page for documents
|
||||||
|
// that are PDFs.
|
||||||
|
for (Bitstream bitstream : bitstreams) {
|
||||||
|
BitstreamFormat format = bitstream.getFormat();
|
||||||
|
|
||||||
|
//If bitstream is a PDF document then it is citable.
|
||||||
|
CitationDocument citationDocument = new CitationDocument();
|
||||||
|
|
||||||
|
if(citationDocument.canGenerateCitationVersion(bitstream)) {
|
||||||
|
this.resBuilder.append(item.getHandle() + " - "
|
||||||
|
+ bitstream.getName() + " is citable.");
|
||||||
|
try {
|
||||||
|
//Create the cited document
|
||||||
|
File citedDocument = citationDocument.makeCitedDocument(bitstream);
|
||||||
|
//Add the cited document to the approiate bundle
|
||||||
|
this.addCitedPageToItem(citedDocument, bundle, pBundle,
|
||||||
|
dBundle, displayMap, item, bitstream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
//Could be many things, but nothing that should be
|
||||||
|
//expected.
|
||||||
|
//Print out some detailed information for debugging.
|
||||||
|
e.printStackTrace();
|
||||||
|
StackTraceElement[] stackTrace = e.getStackTrace();
|
||||||
|
StringBuilder stack = new StringBuilder();
|
||||||
|
int numLines = Math.min(stackTrace.length, 12);
|
||||||
|
for (int j = 0; j < numLines; j++) {
|
||||||
|
stack.append("\t" + stackTrace[j].toString() + "\n");
|
||||||
|
}
|
||||||
|
if (stackTrace.length > numLines) {
|
||||||
|
stack.append("\t. . .\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.error(e.toString() + " -> \n" + stack.toString());
|
||||||
|
this.resBuilder.append(", but there was an error generating the PDF.\n");
|
||||||
|
this.status = Curator.CURATE_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//bitstream is not a document
|
||||||
|
this.resBuilder.append(item.getHandle() + " - "
|
||||||
|
+ bitstream.getName() + " is not citable.\n");
|
||||||
|
this.status = Curator.CURATE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function for {@link CitationPage#performItem(Item)}. This function takes in the
|
||||||
|
* cited document as a File and adds it to DSpace properly.
|
||||||
|
*
|
||||||
|
* @param citedTemp The temporary File that is the cited document.
|
||||||
|
* @param bundle The bundle the cited file is from.
|
||||||
|
* @param pBundle The preservation bundle. The original document should be
|
||||||
|
* put in here if it is not already.
|
||||||
|
* @param dBundle The display bundle. The cited document gets put in here.
|
||||||
|
* @param displayMap The map of bitstream names to bitstreams in the display
|
||||||
|
* bundle.
|
||||||
|
* @param item The item containing the bundles being used.
|
||||||
|
* @param bitstream The original source bitstream.
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws AuthorizeException
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void addCitedPageToItem(File citedTemp, Bundle bundle, Bundle pBundle,
|
||||||
|
Bundle dBundle, Map<String,Bitstream> displayMap, Item item,
|
||||||
|
Bitstream bitstream) throws SQLException, AuthorizeException, IOException {
|
||||||
|
//If we are modifying a file that is not in the
|
||||||
|
//preservation bundle then we have to move it there.
|
||||||
|
if (bundle.getID() != pBundle.getID()) {
|
||||||
|
pBundle.addBitstream(bitstream);
|
||||||
|
bundle.removeBitstream(bitstream);
|
||||||
|
Bitstream[] originalBits = bundle.getBitstreams();
|
||||||
|
if (originalBits == null || originalBits.length == 0) {
|
||||||
|
item.removeBundle(bundle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create an input stream form the temporary file
|
||||||
|
//that is the cited document and create a
|
||||||
|
//bitstream from it.
|
||||||
|
InputStream inp = new FileInputStream(citedTemp);
|
||||||
|
if (displayMap.containsKey(bitstream.getName())) {
|
||||||
|
dBundle.removeBitstream(displayMap.get(bitstream.getName()));
|
||||||
|
}
|
||||||
|
Bitstream citedBitstream = dBundle.createBitstream(inp);
|
||||||
|
inp.close(); //Close up the temporary InputStream
|
||||||
|
|
||||||
|
//Setup a good name for our bitstream and make
|
||||||
|
//it the same format as the source document.
|
||||||
|
citedBitstream.setName(bitstream.getName());
|
||||||
|
citedBitstream.setFormat(bitstream.getFormat());
|
||||||
|
citedBitstream.setDescription(bitstream.getDescription());
|
||||||
|
|
||||||
|
this.resBuilder.append(" Added "
|
||||||
|
+ citedBitstream.getName()
|
||||||
|
+ " to the " + CitationPage.DISPLAY_BUNDLE_NAME + " bundle.\n");
|
||||||
|
|
||||||
|
//Run update to propagate changes to the
|
||||||
|
//database.
|
||||||
|
item.update();
|
||||||
|
this.status = Curator.CURATE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,665 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.disseminate;
|
||||||
|
|
||||||
|
import com.itextpdf.text.*;
|
||||||
|
import com.itextpdf.text.pdf.*;
|
||||||
|
import com.itextpdf.text.pdf.draw.LineSeparator;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.AuthorizeManager;
|
||||||
|
import org.dspace.content.*;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.core.ConfigurationManager;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.handle.HandleManager;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Citation Document produces a dissemination package (DIP) that is different that the archival package (AIP).
|
||||||
|
* In this case we append the descriptive metadata to the end (configurable) of the document. i.e. last page of PDF.
|
||||||
|
* So instead of getting the original PDF, you get a cPDF (with citation information added).
|
||||||
|
*
|
||||||
|
* @author Peter Dietz (dietz.72@osu.edu)
|
||||||
|
*/
|
||||||
|
public class CitationDocument {
|
||||||
|
/**
|
||||||
|
* Class Logger
|
||||||
|
*/
|
||||||
|
private static Logger log = Logger.getLogger(CitationDocument.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of MIME types that can have a citation page added to them. That is,
|
||||||
|
* MIME types in this set can be converted to a PDF which is then prepended
|
||||||
|
* with a citation page.
|
||||||
|
*/
|
||||||
|
private static final Set<String> VALID_TYPES = new HashSet<String>(2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of MIME types that refer to a PDF
|
||||||
|
*/
|
||||||
|
private static final Set<String> PDF_MIMES = new HashSet<String>(2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of MIME types that refer to a JPEG, PNG, or GIF
|
||||||
|
*/
|
||||||
|
private static final Set<String> RASTER_MIMES = new HashSet<String>();
|
||||||
|
/**
|
||||||
|
* A set of MIME types that refer to a SVG
|
||||||
|
*/
|
||||||
|
private static final Set<String> SVG_MIMES = new HashSet<String>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comma separated list of collections handles to enable citation for.
|
||||||
|
* webui.citation.enabled_collections, default empty/none. ex: =1811/123, 1811/345
|
||||||
|
*/
|
||||||
|
private static String citationEnabledCollections = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comma separated list of community handles to enable citation for.
|
||||||
|
* webui.citation.enabled_communties, default empty/none. ex: =1811/123, 1811/345
|
||||||
|
*/
|
||||||
|
private static String citationEnabledCommunities = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of all enabled collections, inherited/determined for those under communities.
|
||||||
|
*/
|
||||||
|
private static ArrayList<String> citationEnabledCollectionsList;
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
// Add valid format MIME types to set. This could be put in the Schema
|
||||||
|
// instead.
|
||||||
|
//Populate RASTER_MIMES
|
||||||
|
SVG_MIMES.add("image/jpeg");
|
||||||
|
SVG_MIMES.add("image/pjpeg");
|
||||||
|
SVG_MIMES.add("image/png");
|
||||||
|
SVG_MIMES.add("image/gif");
|
||||||
|
//Populate SVG_MIMES
|
||||||
|
SVG_MIMES.add("image/svg");
|
||||||
|
SVG_MIMES.add("image/svg+xml");
|
||||||
|
|
||||||
|
|
||||||
|
//Populate PDF_MIMES
|
||||||
|
PDF_MIMES.add("application/pdf");
|
||||||
|
PDF_MIMES.add("application/x-pdf");
|
||||||
|
|
||||||
|
//Populate VALID_TYPES
|
||||||
|
VALID_TYPES.addAll(PDF_MIMES);
|
||||||
|
|
||||||
|
|
||||||
|
//Load enabled collections
|
||||||
|
citationEnabledCollections = ConfigurationManager.getProperty("disseminate-citation", "enabled_collections");
|
||||||
|
citationEnabledCollectionsList = new ArrayList<String>();
|
||||||
|
if(citationEnabledCollections != null && citationEnabledCollections.length() > 0) {
|
||||||
|
String[] collectionChunks = citationEnabledCollections.split(",");
|
||||||
|
for(String collectionString : collectionChunks) {
|
||||||
|
citationEnabledCollectionsList.add(collectionString.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Load enabled communities, and add to collection-list
|
||||||
|
citationEnabledCommunities = ConfigurationManager.getProperty("disseminate-citation", "enabled_communities");
|
||||||
|
if(citationEnabledCollectionsList == null) {
|
||||||
|
citationEnabledCollectionsList = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(citationEnabledCommunities != null && citationEnabledCommunities.length() > 0) {
|
||||||
|
try {
|
||||||
|
String[] communityChunks = citationEnabledCommunities.split(",");
|
||||||
|
for(String communityString : communityChunks) {
|
||||||
|
Context context = new Context();
|
||||||
|
DSpaceObject dsoCommunity = HandleManager.resolveToObject(context, communityString.trim());
|
||||||
|
if(dsoCommunity instanceof Community) {
|
||||||
|
Community community = (Community)dsoCommunity;
|
||||||
|
Collection[] collections = community.getAllCollections();
|
||||||
|
|
||||||
|
for(Collection collection : collections) {
|
||||||
|
citationEnabledCollectionsList.add(collection.getHandle());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("Invalid community for citation.enabled_communities, value:" + communityString.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public CitationDocument() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean to determine is citation-functionality is enabled globally for entire site.
|
||||||
|
* config/module/disseminate-citation: enable_globally, default false. true=on, false=off
|
||||||
|
*/
|
||||||
|
private static Boolean citationEnabledGlobally = null;
|
||||||
|
|
||||||
|
private static boolean isCitationEnabledGlobally() {
|
||||||
|
if(citationEnabledGlobally == null) {
|
||||||
|
citationEnabledGlobally = ConfigurationManager.getBooleanProperty("disseminate-citation", "enable_globally", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return citationEnabledGlobally;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isCitationEnabledThroughCollection(Bitstream bitstream) throws SQLException {
|
||||||
|
//TODO Should we re-check configs, and set the collections list?
|
||||||
|
|
||||||
|
//Reject quickly if no-enabled collections
|
||||||
|
if(citationEnabledCollectionsList.size() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DSpaceObject owningDSO = bitstream.getParentObject();
|
||||||
|
if(owningDSO instanceof Item) {
|
||||||
|
Item item = (Item)owningDSO;
|
||||||
|
|
||||||
|
Collection[] collections = item.getCollections();
|
||||||
|
|
||||||
|
for(Collection collection : collections) {
|
||||||
|
if(citationEnabledCollectionsList.contains(collection.getHandle())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If previous logic didn't return true, then we're false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository policy can specify to have a custom citation cover/tail page to the document, which embeds metadata.
|
||||||
|
* We need to determine if we will intercept this bitstream download, and give out a citation dissemination rendition.
|
||||||
|
*
|
||||||
|
* What will trigger a redirect/intercept?
|
||||||
|
* Citation enabled globally (all citable bitstreams will get "watermarked") modules/disseminate-citation: enable_globally
|
||||||
|
* OR
|
||||||
|
* The container is this object is whitelist enabled.
|
||||||
|
* - community: modules/disseminate-citation: enabled_communities
|
||||||
|
* - collection: modules/disseminate-citation: enabled_collections
|
||||||
|
* AND
|
||||||
|
* This User is not an admin. (Admins need to be able to view the "raw" original instead.)
|
||||||
|
* AND
|
||||||
|
* This object is citation-able (presently, just PDF)
|
||||||
|
*
|
||||||
|
* The module must be enabled, before the permission level checks happen.
|
||||||
|
* @param bitstream
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Boolean isCitationEnabledForBitstream(Bitstream bitstream, Context context) throws SQLException {
|
||||||
|
if(isCitationEnabledGlobally() || isCitationEnabledThroughCollection(bitstream)) {
|
||||||
|
|
||||||
|
boolean adminUser = AuthorizeManager.isAdmin(context);
|
||||||
|
|
||||||
|
if(!adminUser && canGenerateCitationVersion(bitstream)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If previous logic didn't return true, then we're false.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should the citation page be the first page of the document, or the last page?
|
||||||
|
* default => true. true => first page, false => last page
|
||||||
|
* citation_as_first_page=true
|
||||||
|
*/
|
||||||
|
private static Boolean citationAsFirstPage = null;
|
||||||
|
|
||||||
|
private static Boolean isCitationFirstPage() {
|
||||||
|
if(citationAsFirstPage == null) {
|
||||||
|
citationAsFirstPage = ConfigurationManager.getBooleanProperty("disseminate-citation", "citation_as_first_page", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return citationAsFirstPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canGenerateCitationVersion(Bitstream bitstream) {
|
||||||
|
return VALID_TYPES.contains(bitstream.getFormat().getMIMEType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public File makeCitedDocument(Bitstream bitstream) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
Item item = (Item) bitstream.getParentObject();
|
||||||
|
CitationMeta cm = new CitationMeta(item);
|
||||||
|
if(cm == null) {
|
||||||
|
log.error("CitationMeta was null");
|
||||||
|
}
|
||||||
|
|
||||||
|
File citedDocumentFile = makeCitedDocument(bitstream, cm);
|
||||||
|
if(citedDocumentFile == null) {
|
||||||
|
log.error("Got a null citedDocumentFile in makeCitedDocument for bitstream");
|
||||||
|
}
|
||||||
|
return citedDocumentFile;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("makeCitedDocument from Bitstream fail!" + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a
|
||||||
|
* cited document from the given bitstream of the given item. This
|
||||||
|
* requires that bitstream is contained in item.
|
||||||
|
* <p>
|
||||||
|
* The Process for adding a cover page is as follows:
|
||||||
|
* <ol>
|
||||||
|
* <li> Load source file into PdfReader and create a
|
||||||
|
* Document to put our cover page into.</li>
|
||||||
|
* <li> Create cover page and add content to it.</li>
|
||||||
|
* <li> Concatenate the coverpage and the source
|
||||||
|
* document.</li>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param bitstream The source bitstream being cited. This must be a PDF.
|
||||||
|
* @param cMeta The citation information used to generate the coverpage.
|
||||||
|
* @return The temporary File that is the finished, cited document.
|
||||||
|
* @throws com.itextpdf.text.DocumentException
|
||||||
|
* @throws java.io.FileNotFoundException
|
||||||
|
* @throws SQLException
|
||||||
|
* @throws org.dspace.authorize.AuthorizeException
|
||||||
|
*/
|
||||||
|
private File makeCitedDocument(Bitstream bitstream, CitationMeta cMeta)
|
||||||
|
throws DocumentException, IOException, SQLException, AuthorizeException {
|
||||||
|
//Read the source bitstream
|
||||||
|
PdfReader source = new PdfReader(bitstream.retrieve());
|
||||||
|
|
||||||
|
Document citedDoc = new Document(PageSize.LETTER);
|
||||||
|
|
||||||
|
File coverTemp = File.createTempFile(bitstream.getName(), ".cover.pdf");
|
||||||
|
|
||||||
|
//Need a writer instance to make changed to the document.
|
||||||
|
PdfWriter writer = PdfWriter.getInstance(citedDoc, new FileOutputStream(coverTemp));
|
||||||
|
|
||||||
|
//Call helper function to add content to the coverpage.
|
||||||
|
this.generateCoverPage(citedDoc, writer, cMeta);
|
||||||
|
|
||||||
|
//Create reader from finished cover page.
|
||||||
|
PdfReader cover = new PdfReader(new FileInputStream(coverTemp));
|
||||||
|
|
||||||
|
//Get page labels from source document
|
||||||
|
String[] labels = PdfPageLabels.getPageLabels(source);
|
||||||
|
|
||||||
|
//Concatenate the finished cover page with the source document.
|
||||||
|
File citedTemp = File.createTempFile(bitstream.getName(), ".cited.pdf");
|
||||||
|
OutputStream citedOut = new FileOutputStream(citedTemp);
|
||||||
|
PdfConcatenate concat = new PdfConcatenate(citedOut);
|
||||||
|
concat.open();
|
||||||
|
|
||||||
|
//Is the citation-page the first page or last-page?
|
||||||
|
if(isCitationFirstPage()) {
|
||||||
|
//citation as cover page
|
||||||
|
concat.addPages(cover);
|
||||||
|
concat.addPages(source);
|
||||||
|
} else {
|
||||||
|
//citation as tail page
|
||||||
|
concat.addPages(source);
|
||||||
|
concat.addPages(cover);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Put all of our labels in from the orignal document.
|
||||||
|
if (labels != null) {
|
||||||
|
PdfPageLabels citedPageLabels = new PdfPageLabels();
|
||||||
|
log.debug("Printing arbitrary page labels.");
|
||||||
|
|
||||||
|
for (int i = 0; i < labels.length; i++) {
|
||||||
|
citedPageLabels.addPageLabel(i + 1, PdfPageLabels.EMPTY, labels[i]);
|
||||||
|
log.debug("Label for page: " + (i + 1) + " -> " + labels[i]);
|
||||||
|
}
|
||||||
|
citedPageLabels.addPageLabel(labels.length + 1, PdfPageLabels.EMPTY, "Citation Page");
|
||||||
|
concat.getWriter().setPageLabels(citedPageLabels);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Close it up
|
||||||
|
concat.close();
|
||||||
|
|
||||||
|
//Close the cover-page
|
||||||
|
writer.close();
|
||||||
|
coverTemp.delete();
|
||||||
|
|
||||||
|
citedTemp.deleteOnExit();
|
||||||
|
return citedTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a DSpace {@link Bitstream} and uses its associated METADATA to
|
||||||
|
* create a cover page.
|
||||||
|
*
|
||||||
|
* @param cDoc The cover page document to add cited information to.
|
||||||
|
* @param writer
|
||||||
|
* @param cMeta
|
||||||
|
* METADATA retrieved from the parent collection.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws DocumentException
|
||||||
|
*/
|
||||||
|
private void generateCoverPage(Document cDoc, PdfWriter writer, CitationMeta cMeta) throws DocumentException {
|
||||||
|
cDoc.open();
|
||||||
|
writer.setCompressionLevel(0);
|
||||||
|
|
||||||
|
Item item = cMeta.getItem();
|
||||||
|
|
||||||
|
//Set up some fonts
|
||||||
|
Font helv26 = FontFactory.getFont(FontFactory.HELVETICA, 26f, BaseColor.BLACK);
|
||||||
|
Font helv16 = FontFactory.getFont(FontFactory.HELVETICA, 16f, BaseColor.BLACK);
|
||||||
|
Font helv12 = FontFactory.getFont(FontFactory.HELVETICA, 12f, BaseColor.BLACK);
|
||||||
|
Font helv12_italic = FontFactory.getFont(FontFactory.HELVETICA_OBLIQUE, 12f, BaseColor.BLACK);
|
||||||
|
Font helv11_bold = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 11f, BaseColor.BLACK);
|
||||||
|
Font helv9 = FontFactory.getFont(FontFactory.HELVETICA, 9f, BaseColor.BLACK);
|
||||||
|
|
||||||
|
// 1 - Header:
|
||||||
|
// University Name
|
||||||
|
// Repository Name repository.url
|
||||||
|
Paragraph university = new Paragraph("The Ohio State University", helv11_bold);
|
||||||
|
cDoc.add(university);
|
||||||
|
|
||||||
|
PdfPTable repositoryTable = new PdfPTable(2);
|
||||||
|
repositoryTable.setWidthPercentage(100);
|
||||||
|
|
||||||
|
Chunk repositoryName = new Chunk("Knowledge Bank", helv11_bold);
|
||||||
|
PdfPCell nameCell = new PdfPCell();
|
||||||
|
nameCell.setBorderWidth(0);
|
||||||
|
nameCell.addElement(repositoryName);
|
||||||
|
|
||||||
|
Chunk repositoryURL = new Chunk("kb.osu.edu", helv11_bold);
|
||||||
|
repositoryURL.setAnchor("http://kb.osu.edu");
|
||||||
|
|
||||||
|
PdfPCell urlCell = new PdfPCell();
|
||||||
|
urlCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
|
||||||
|
urlCell.setBorderWidth(0);
|
||||||
|
urlCell.addElement(repositoryURL);
|
||||||
|
|
||||||
|
repositoryTable.addCell(nameCell);
|
||||||
|
repositoryTable.addCell(urlCell);
|
||||||
|
|
||||||
|
repositoryTable.setSpacingAfter(5);
|
||||||
|
|
||||||
|
cDoc.add(repositoryTable);
|
||||||
|
|
||||||
|
// Line Separator
|
||||||
|
LineSeparator lineSeparator = new LineSeparator();
|
||||||
|
cDoc.add(lineSeparator);
|
||||||
|
|
||||||
|
// 2 - Bread Crumbs
|
||||||
|
// Community Name Collection Name
|
||||||
|
PdfPTable breadcrumbTable = new PdfPTable(2);
|
||||||
|
breadcrumbTable.setWidthPercentage(100);
|
||||||
|
|
||||||
|
Chunk communityName = new Chunk(getOwningCommunity(item), helv9);
|
||||||
|
PdfPCell commCell = new PdfPCell();
|
||||||
|
commCell.setBorderWidth(0);
|
||||||
|
commCell.addElement(communityName);
|
||||||
|
|
||||||
|
Chunk collectionName = new Chunk(getOwningCollection(item), helv9);
|
||||||
|
PdfPCell collCell = new PdfPCell();
|
||||||
|
collCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
|
||||||
|
collCell.setBorderWidth(0);
|
||||||
|
collCell.addElement(collectionName);
|
||||||
|
|
||||||
|
breadcrumbTable.addCell(commCell);
|
||||||
|
breadcrumbTable.addCell(collCell);
|
||||||
|
|
||||||
|
breadcrumbTable.setSpacingBefore(5);
|
||||||
|
breadcrumbTable.setSpacingAfter(5);
|
||||||
|
|
||||||
|
cDoc.add(breadcrumbTable);
|
||||||
|
|
||||||
|
// Line Separator
|
||||||
|
cDoc.add(lineSeparator);
|
||||||
|
|
||||||
|
// 3 - Metadata
|
||||||
|
// date.issued
|
||||||
|
// dc.title
|
||||||
|
// dc.creator; dc.creator
|
||||||
|
Paragraph dateIssued = new Paragraph(item.getMetadata("dc.date.issued"), helv12);
|
||||||
|
dateIssued.setSpacingBefore(20);
|
||||||
|
cDoc.add(dateIssued);
|
||||||
|
|
||||||
|
Paragraph title = new Paragraph(item.getName(), helv26);
|
||||||
|
title.setSpacingBefore(15);
|
||||||
|
cDoc.add(title);
|
||||||
|
|
||||||
|
Paragraph creators = new Paragraph(getAllMetadataSeperated(item, "dc.creator"), helv16);
|
||||||
|
creators.setSpacingBefore(30);
|
||||||
|
creators.setSpacingAfter(20);
|
||||||
|
cDoc.add(creators);
|
||||||
|
|
||||||
|
// Line Separator
|
||||||
|
cDoc.add(lineSeparator);
|
||||||
|
|
||||||
|
// 4 - Citation
|
||||||
|
// dc.identifier.citation
|
||||||
|
// dc.identifier.uri
|
||||||
|
Paragraph citation = new Paragraph(item.getMetadata("dc.identifier.citation"), helv12);
|
||||||
|
|
||||||
|
Chunk identifierChunk = new Chunk(item.getMetadata("dc.identifier.uri"), helv12);
|
||||||
|
identifierChunk.setAnchor(item.getMetadata("dc.identifier.uri"));
|
||||||
|
|
||||||
|
Paragraph identifier = new Paragraph();
|
||||||
|
identifier.add(identifierChunk);
|
||||||
|
|
||||||
|
|
||||||
|
cDoc.add(citation);
|
||||||
|
cDoc.add(identifier);
|
||||||
|
|
||||||
|
// 5 - License
|
||||||
|
// Downloaded from the Knowledge Bank, The Ohio State University's institutional repository
|
||||||
|
Paragraph license = new Paragraph("Downloaded from the Knowledge Bank, The Ohio State University's institutional repository", helv12_italic);
|
||||||
|
license.setSpacingBefore(10);
|
||||||
|
cDoc.add(license);
|
||||||
|
|
||||||
|
cDoc.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to add a Logo to the document from the given resource. Returns
|
||||||
|
* true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @param doc The document to add the logo to. (Added to the top right
|
||||||
|
* corner of the first page.
|
||||||
|
* @param writer The writer associated with the given Document.
|
||||||
|
* @param res The resource/path to the logo file. This file can be any of
|
||||||
|
* the following formats:
|
||||||
|
* GIF, PNG, JPEG, PDF
|
||||||
|
*
|
||||||
|
* @return Succesfully added logo to document.
|
||||||
|
*/
|
||||||
|
private boolean addLogoToDocument(Document doc, PdfWriter writer, String res) {
|
||||||
|
boolean ret = false;
|
||||||
|
try {
|
||||||
|
//First we try to get the logo as if it is a Java Resource
|
||||||
|
URL logoURL = this.getClass().getResource(res);
|
||||||
|
log.debug(res + " -> " + logoURL.toString());
|
||||||
|
if (logoURL == null) {
|
||||||
|
logoURL = new URL(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logoURL != null) {
|
||||||
|
String mtype = URLConnection.guessContentTypeFromStream(logoURL.openStream());
|
||||||
|
if (mtype == null) {
|
||||||
|
mtype = URLConnection.guessContentTypeFromName(res);
|
||||||
|
}
|
||||||
|
log.debug("Determined MIMETYPE of logo: " + mtype);
|
||||||
|
if (PDF_MIMES.contains(mtype)) {
|
||||||
|
//Handle pdf logos.
|
||||||
|
PdfReader reader = new PdfReader(logoURL);
|
||||||
|
PdfImportedPage logoPage = writer.getImportedPage(reader, 1);
|
||||||
|
Image logo = Image.getInstance(logoPage);
|
||||||
|
float x = doc.getPageSize().getWidth() - doc.rightMargin() - logo.getScaledWidth();
|
||||||
|
float y = doc.getPageSize().getHeight() - doc.topMargin() - logo.getScaledHeight();
|
||||||
|
logo.setAbsolutePosition(x, y);
|
||||||
|
doc.add(logo);
|
||||||
|
ret = true;
|
||||||
|
} else if (RASTER_MIMES.contains(mtype)) {
|
||||||
|
//Use iText's Image class
|
||||||
|
Image logo = Image.getInstance(logoURL);
|
||||||
|
|
||||||
|
//Determine the position of the logo (upper-right corner) and
|
||||||
|
//place it there.
|
||||||
|
float x = doc.getPageSize().getWidth() - doc.rightMargin() - logo.getScaledWidth();
|
||||||
|
float y = doc.getPageSize().getHeight() - doc.topMargin() - logo.getScaledHeight();
|
||||||
|
logo.setAbsolutePosition(x, y);
|
||||||
|
writer.getDirectContent().addImage(logo);
|
||||||
|
ret = true;
|
||||||
|
} else if (SVG_MIMES.contains(mtype)) {
|
||||||
|
//Handle SVG Logos
|
||||||
|
log.error("SVG Logos are not supported yet.");
|
||||||
|
} else {
|
||||||
|
//Cannot use other mimetypes
|
||||||
|
log.debug("Logo MIMETYPE is not supported.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.debug("Could not create URL to Logo resource: " + res);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Could not add logo (" + res + ") to cited document: "
|
||||||
|
+ e.getMessage());
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOwningCommunity(Item item) {
|
||||||
|
try {
|
||||||
|
Community[] comms = item.getCommunities();
|
||||||
|
if(comms.length > 0) {
|
||||||
|
return comms[0].getName();
|
||||||
|
} else {
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOwningCollection(Item item) {
|
||||||
|
try {
|
||||||
|
return item.getOwningCollection().getName();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAllMetadataSeperated(Item item, String metadataKey) {
|
||||||
|
DCValue[] dcValues = item.getMetadataByMetadataString(metadataKey);
|
||||||
|
|
||||||
|
ArrayList<String> valueArray = new ArrayList<String>();
|
||||||
|
|
||||||
|
for(DCValue dcValue : dcValues) {
|
||||||
|
valueArray.add(dcValue.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtils.join(valueArray.toArray(), "; ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This wraps the item used in its constructor to make it easier to access
|
||||||
|
* METADATA.
|
||||||
|
*/
|
||||||
|
private class CitationMeta {
|
||||||
|
private Collection parent;
|
||||||
|
private Map<String, String> metaData;
|
||||||
|
private Item myItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs CitationMeta object from an Item. It uses item specific
|
||||||
|
* METADATA as well as METADATA from the owning collection.
|
||||||
|
*
|
||||||
|
* @param item An Item to get METADATA from.
|
||||||
|
* @throws java.sql.SQLException
|
||||||
|
*/
|
||||||
|
public CitationMeta(Item item) throws SQLException {
|
||||||
|
this.myItem = item;
|
||||||
|
this.metaData = new HashMap<String, String>();
|
||||||
|
//Get all METADATA from our this.myItem
|
||||||
|
DCValue[] dcvs = this.myItem.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||||
|
//Put METADATA in a Map for easy access.
|
||||||
|
for (DCValue dsv : dcvs) {
|
||||||
|
String[] dsvParts = {dsv.schema, dsv.element, dsv.qualifier, dsv.language, dsv.authority};
|
||||||
|
StringBuilder keyBuilder = new StringBuilder();
|
||||||
|
for (String part : dsvParts) {
|
||||||
|
if (part != null && part != "") {
|
||||||
|
keyBuilder.append(part + '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Remove the trailing '.'
|
||||||
|
keyBuilder.deleteCharAt(keyBuilder.length() - 1);
|
||||||
|
this.metaData.put(keyBuilder.toString(), dsv.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Get METADATA from the owning Collection
|
||||||
|
this.parent = this.myItem.getOwningCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a map of the METADATA for the item associated with this
|
||||||
|
* instance of CitationMeta.
|
||||||
|
*
|
||||||
|
* @return a Map of the METADATA for the associated item.
|
||||||
|
*/
|
||||||
|
public Map<String, String> getMetaData() {
|
||||||
|
return this.metaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getItem() {
|
||||||
|
return this.myItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection getCollection() {
|
||||||
|
return this.parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @see Object#toString()
|
||||||
|
* @return A string with the format:
|
||||||
|
* CitationPage.CitationMeta {
|
||||||
|
* CONTENT
|
||||||
|
* }
|
||||||
|
* Where CONTENT is the METADATA derived by this class.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder ret = new StringBuilder(CitationMeta.class.getName());
|
||||||
|
ret.append(" {<br />\n\t");
|
||||||
|
ret.append(this.parent.getName());
|
||||||
|
ret.append("\n\t");
|
||||||
|
ret.append(this.myItem.getName());
|
||||||
|
ret.append("\n\t");
|
||||||
|
ret.append(this.metaData);
|
||||||
|
ret.append("\n}\n");
|
||||||
|
return ret.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -7,9 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.dspace.app.xmlui.cocoon;
|
package org.dspace.app.xmlui.cocoon;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -42,6 +40,7 @@ import org.dspace.content.Item;
|
|||||||
import org.dspace.core.ConfigurationManager;
|
import org.dspace.core.ConfigurationManager;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.disseminate.CitationDocument;
|
||||||
import org.dspace.handle.HandleManager;
|
import org.dspace.handle.HandleManager;
|
||||||
import org.dspace.usage.UsageEvent;
|
import org.dspace.usage.UsageEvent;
|
||||||
import org.dspace.utils.DSpace;
|
import org.dspace.utils.DSpace;
|
||||||
@@ -157,6 +156,9 @@ public class BitstreamReader extends AbstractReader implements Recyclable
|
|||||||
/** True if user agent making this request was identified as spider. */
|
/** True if user agent making this request was identified as spider. */
|
||||||
private boolean isSpider = false;
|
private boolean isSpider = false;
|
||||||
|
|
||||||
|
/** TEMP file for citation PDF. We will save here, so we can delete the temp file when done. */
|
||||||
|
private File tempFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the bitstream reader.
|
* Set up the bitstream reader.
|
||||||
*
|
*
|
||||||
@@ -320,8 +322,50 @@ public class BitstreamReader extends AbstractReader implements Recyclable
|
|||||||
|
|
||||||
// Success, bitstream found and the user has access to read it.
|
// Success, bitstream found and the user has access to read it.
|
||||||
// Store these for later retrieval:
|
// Store these for later retrieval:
|
||||||
|
|
||||||
|
// Intercepting views to the original bitstream to instead show a citation altered version of the object
|
||||||
|
// We need to check if this resource falls under the "show watermarked alternative" umbrella.
|
||||||
|
// At which time we will not return the "bitstream", but will instead on-the-fly generate the citation rendition.
|
||||||
|
|
||||||
|
// What will trigger a redirect/intercept?
|
||||||
|
// 1) Intercepting Enabled
|
||||||
|
// 2) This User is not an admin
|
||||||
|
// 3) This object is citation-able
|
||||||
|
if (CitationDocument.isCitationEnabledForBitstream(bitstream, context)) {
|
||||||
|
// on-the-fly citation generator
|
||||||
|
log.info(item.getHandle() + " - " + bitstream.getName() + " is citable.");
|
||||||
|
|
||||||
|
FileInputStream fileInputStream = null;
|
||||||
|
CitationDocument citationDocument = new CitationDocument();
|
||||||
|
|
||||||
|
try {
|
||||||
|
//Create the cited document
|
||||||
|
tempFile = citationDocument.makeCitedDocument(bitstream);
|
||||||
|
if(tempFile == null) {
|
||||||
|
log.error("CitedDocument was null");
|
||||||
|
} else {
|
||||||
|
log.info("CitedDocument was ok," + tempFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fileInputStream = new FileInputStream(tempFile);
|
||||||
|
if(fileInputStream == null) {
|
||||||
|
log.error("Error opening fileInputStream: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bitstreamInputStream = fileInputStream;
|
||||||
|
this.bitstreamSize = tempFile.length();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Caught an error with intercepting the citation document:" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
//End of CitationDocument
|
||||||
|
} else {
|
||||||
this.bitstreamInputStream = bitstream.retrieve();
|
this.bitstreamInputStream = bitstream.retrieve();
|
||||||
this.bitstreamSize = bitstream.getSize();
|
this.bitstreamSize = bitstream.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
this.bitstreamMimeType = bitstream.getFormat().getMIMEType();
|
this.bitstreamMimeType = bitstream.getFormat().getMIMEType();
|
||||||
this.bitstreamName = bitstream.getName();
|
this.bitstreamName = bitstream.getName();
|
||||||
if (context.getCurrentUser() == null)
|
if (context.getCurrentUser() == null)
|
||||||
@@ -351,9 +395,18 @@ public class BitstreamReader extends AbstractReader implements Recyclable
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// In case there is no bitstream name...
|
// In-case there is no bitstream name...
|
||||||
|
if(name != null && name.length() > 0) {
|
||||||
|
bitstreamName = name;
|
||||||
|
if(name.endsWith(".jpg")) {
|
||||||
|
bitstreamMimeType = "image/jpeg";
|
||||||
|
} else if(name.endsWith(".png")) {
|
||||||
|
bitstreamMimeType = "image/png";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
bitstreamName = "bitstream";
|
bitstreamName = "bitstream";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Log that the bitstream has been viewed, this is non-cached and the complexity
|
// Log that the bitstream has been viewed, this is non-cached and the complexity
|
||||||
// of adding it to the sitemap for every possible bitstream uri is not very tractable
|
// of adding it to the sitemap for every possible bitstream uri is not very tractable
|
||||||
|
15
dspace/config/modules/disseminate-citation.cfg
Normal file
15
dspace/config/modules/disseminate-citation.cfg
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#Boolean to determine is citation-functionality is enabled globally for entire site.
|
||||||
|
#default => false
|
||||||
|
enable_globally=true
|
||||||
|
|
||||||
|
#List of collection handles to enable, to apply to nested bitstreams within
|
||||||
|
#default => empty. This is to be collection handles, separated by commas. ex: 1811/123, 1811/234
|
||||||
|
#enabled_collections=
|
||||||
|
|
||||||
|
#List of community handles to enable, to apply to nested bitstreams within
|
||||||
|
#default => empty. This is to be community handles, separated by commas. ex: 1811/222, 1811/333
|
||||||
|
#enabled_communities=
|
||||||
|
|
||||||
|
#Should the citation page be the first page of the document, or the last page?
|
||||||
|
#default => true. true => first page, false => last page
|
||||||
|
#citation_as_first_page=true
|
Reference in New Issue
Block a user