mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Compare commits
73 Commits
6ac823d29a
...
dspace-1_7
Author | SHA1 | Date | |
---|---|---|---|
![]() |
99f11afc00 | ||
![]() |
d1afd58c7d | ||
![]() |
96184cad90 | ||
![]() |
e782449835 | ||
![]() |
a993c9a3c1 | ||
![]() |
23da4c607c | ||
![]() |
1bf23d7c4c | ||
![]() |
38ef9080fa | ||
![]() |
17be1b9c25 | ||
![]() |
deaf6a5d82 | ||
![]() |
16b5ebfdea | ||
![]() |
e320ebd85a | ||
![]() |
e8d7f30ccf | ||
![]() |
36fa23246c | ||
![]() |
ca21676305 | ||
![]() |
266ec0fc2b | ||
![]() |
7e1e0ce8b5 | ||
![]() |
faf8883bc9 | ||
![]() |
43fc41fef9 | ||
![]() |
d863d8a88c | ||
![]() |
21f7f3f9ca | ||
![]() |
37a6f5e82a | ||
![]() |
f6f0104cd4 | ||
![]() |
4e6973a569 | ||
![]() |
aa8dd60640 | ||
![]() |
b997ca866f | ||
![]() |
5c6c7e1fd1 | ||
![]() |
6e026ed6fd | ||
![]() |
c3a48caca4 | ||
![]() |
39538b1ab8 | ||
![]() |
f923f7c391 | ||
![]() |
97e105b88f | ||
![]() |
4eaacd90cb | ||
![]() |
9a075ac5d9 | ||
![]() |
f43e2e2992 | ||
![]() |
06b81964e4 | ||
![]() |
84042ce512 | ||
![]() |
3c7d8ba607 | ||
![]() |
151afeace5 | ||
![]() |
aa6f1baa4a | ||
![]() |
2b67c5ccb2 | ||
![]() |
06878eab58 | ||
![]() |
7cc9a5d3d0 | ||
![]() |
8237d8b6e1 | ||
![]() |
48777df275 | ||
![]() |
908429570c | ||
![]() |
d999d0b0b7 | ||
![]() |
2bfd77e634 | ||
![]() |
0a50305ff5 | ||
![]() |
0bf155628d | ||
![]() |
1bbea4dbc4 | ||
![]() |
edb6a8a86f | ||
![]() |
491ca830a9 | ||
![]() |
09e049739f | ||
![]() |
0a00a8bbe9 | ||
![]() |
0cbeef4010 | ||
![]() |
27ae52c8f1 | ||
![]() |
2834c8ccf6 | ||
![]() |
1a9a7dfcba | ||
![]() |
27741e59a9 | ||
![]() |
1f4e370234 | ||
![]() |
f8c0886738 | ||
![]() |
296a70b4d8 | ||
![]() |
c0f8854398 | ||
![]() |
f7e2723e5c | ||
![]() |
314011e069 | ||
![]() |
aa708a326c | ||
![]() |
ce3a2098e4 | ||
![]() |
28bf3e3046 | ||
![]() |
793974234d | ||
![]() |
7ea045b2ed | ||
![]() |
54d0316724 | ||
![]() |
77573bc55f |
14
.gitattributes
vendored
Normal file
14
.gitattributes
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
## Ignore the MVN compiled output directories from version tracking
|
||||
target/
|
||||
|
||||
## Ignore project files created by Eclipse
|
||||
.settings/
|
||||
.project
|
||||
.classpath
|
||||
|
||||
## Ignore project files created by IntelliJ IDEA
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
## Ignore project files created by NetBeans
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
META-INF/
|
1
.travis.yml
Normal file
1
.travis.yml
Normal file
@@ -0,0 +1 @@
|
||||
language: java
|
2
LICENSE
2
LICENSE
@@ -1,7 +1,7 @@
|
||||
DSpace source code license:
|
||||
|
||||
|
||||
Copyright (c) 2002-2010, DuraSpace. All rights reserved.
|
||||
Copyright (c) 2002-2011, DuraSpace. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
5
LICENSE_HEADER
Normal file
5
LICENSE_HEADER
Normal file
@@ -0,0 +1,5 @@
|
||||
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/
|
4
NOTICE
4
NOTICE
@@ -11,5 +11,5 @@ access and preservation of digital works. The Foundation was able to transfer
|
||||
the legal copyright from Hewlett-Packard Company (HP) and Massachusetts
|
||||
Institute of Technology (MIT) to the DSpace Foundation in October 2007. Many
|
||||
of the files in the source code may contain a copyright statement stating HP
|
||||
and MIT posses the copyright, in these instances please note that the copy
|
||||
right has transfered to the DSpace foundation, and subsequently to Duraspace.
|
||||
and MIT possess the copyright, in these instances please note that the copy
|
||||
right has transferred to the DSpace foundation, and subsequently to DuraSpace.
|
||||
|
10
README
10
README
@@ -5,9 +5,9 @@ or
|
||||
- dspace/docs/pdf/DSpace-Manual.pdf
|
||||
|
||||
DSpace version information can be found in this release package under
|
||||
- dspace/CHANGES
|
||||
or
|
||||
- dspace/docs/html/History.html
|
||||
or viewed online at
|
||||
- https://wiki.duraspace.org/display/DSDOC/History
|
||||
|
||||
Documentation for the most recent stable release(s) may be downloaded
|
||||
or viewed online at
|
||||
@@ -31,12 +31,12 @@ mailing list.
|
||||
|
||||
Detailed Issue Tracking for DSpace is done on our JIRA Issue Tracker
|
||||
|
||||
- http://jira.dspace.org/
|
||||
- https://jira.duraspace.org/browse/DS
|
||||
|
||||
|
||||
To contribute to DSpace, please see:
|
||||
|
||||
- https://wiki.duraspace.org/display/DSPACE/HowToContribute
|
||||
- https://wiki.duraspace.org/display/DSPACE/How+to+Contribute+to+DSpace
|
||||
|
||||
|
||||
For more details about DSpace, including a list of service providers,
|
||||
@@ -48,4 +48,4 @@ places to seek help, news articles and lists of other users, please see:
|
||||
DSpace source code licensing information available online at:
|
||||
- http://www.dspace.org/license/
|
||||
|
||||
Copyright (c) 2002-2010, DuraSpace. All rights reserved.
|
||||
Copyright (c) 2002-2011, DuraSpace. All rights reserved.
|
||||
|
@@ -8,24 +8,19 @@
|
||||
|
||||
<!--
|
||||
A Parent POM that Maven inherits DSpace Defaults
|
||||
POM atrributes from.
|
||||
POM attributes from.
|
||||
-->
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update against
|
||||
when changes have occured, this spawns a new build cycle and releases snapshots
|
||||
into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace</connection>
|
||||
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<!--
|
||||
Runtime and Compile Time dependencies for DSpace.
|
||||
@@ -60,29 +55,6 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.google.code.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<configuration>
|
||||
<header>http://scm.dspace.org/svn/repo/licenses/LICENSE_HEADER</header>
|
||||
<includes>
|
||||
<include>src/**</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>src/test/resources/dspaceFolder/**</exclude>
|
||||
</excludes>
|
||||
<properties />
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
@@ -277,6 +249,16 @@
|
||||
<artifactId>contiperf</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<groupId>org.rometools</groupId>
|
||||
<artifactId>rome-modules</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.coverity.security</groupId>
|
||||
<artifactId>coverity-escapers</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@@ -1,338 +1,338 @@
|
||||
/**
|
||||
* 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.app.bulkedit;
|
||||
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.Collection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class to store changes to item that may occur during a batch edit.
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public class BulkEditChange
|
||||
{
|
||||
/** The item these changes relate to */
|
||||
private Item item;
|
||||
|
||||
/** The List of hashtables with the new elements */
|
||||
private List<DCValue> adds;
|
||||
|
||||
/** The List of hashtables with the removed elements */
|
||||
private List<DCValue> removes;
|
||||
|
||||
/** The List of hashtables with the unchanged elements */
|
||||
private List<DCValue> constant;
|
||||
|
||||
/** The List of the complete set of new values (constant + adds) */
|
||||
private List<DCValue> complete;
|
||||
|
||||
/** The list of old collections the item used to be mapped to */
|
||||
private List<Collection> oldMappedCollections;
|
||||
|
||||
/** The list of new collections the item has been mapped into */
|
||||
private List<Collection> newMappedCollections;
|
||||
|
||||
/** The old owning collection */
|
||||
private Collection oldOwningCollection;
|
||||
|
||||
/** The new owning collection */
|
||||
private Collection newOwningCollection;
|
||||
|
||||
/** Is this a new item */
|
||||
private boolean newItem;
|
||||
|
||||
/** Have any changes actually been made? */
|
||||
private boolean empty;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise a change holder for a new item
|
||||
*/
|
||||
public BulkEditChange()
|
||||
{
|
||||
// Set the item to be null
|
||||
item = null;
|
||||
newItem = true;
|
||||
empty = true;
|
||||
oldOwningCollection = null;
|
||||
newOwningCollection = null;
|
||||
|
||||
// Initialise the arrays
|
||||
adds = new ArrayList<DCValue>();
|
||||
removes = new ArrayList<DCValue>();
|
||||
constant = new ArrayList<DCValue>();
|
||||
complete = new ArrayList<DCValue>();
|
||||
oldMappedCollections = new ArrayList<Collection>();
|
||||
newMappedCollections = new ArrayList<Collection>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise a new change holder for an existing item
|
||||
*
|
||||
* @param i The Item to store
|
||||
*/
|
||||
public BulkEditChange(Item i)
|
||||
{
|
||||
// Store the item
|
||||
item = i;
|
||||
newItem = false;
|
||||
empty = true;
|
||||
|
||||
// Initialise the arrays
|
||||
adds = new ArrayList<DCValue>();
|
||||
removes = new ArrayList<DCValue>();
|
||||
constant = new ArrayList<DCValue>();
|
||||
complete = new ArrayList<DCValue>();
|
||||
oldMappedCollections = new ArrayList<Collection>();
|
||||
newMappedCollections = new ArrayList<Collection>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the item - used when a new item is created
|
||||
*
|
||||
* @param i The item
|
||||
*/
|
||||
public void setItem(Item i)
|
||||
{
|
||||
// Store the item
|
||||
item = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an added metadata value
|
||||
*
|
||||
* @param dcv The value to add
|
||||
*/
|
||||
public void registerAdd(DCValue dcv)
|
||||
{
|
||||
// Add the added value
|
||||
adds.add(dcv);
|
||||
complete.add(dcv);
|
||||
empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a removed metadata value
|
||||
*
|
||||
* @param dcv The value to remove
|
||||
*/
|
||||
public void registerRemove(DCValue dcv)
|
||||
{
|
||||
// Add the removed value
|
||||
removes.add(dcv);
|
||||
empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an unchanged metadata value
|
||||
*
|
||||
* @param dcv The value to keep unchanged
|
||||
*/
|
||||
public void registerConstant(DCValue dcv)
|
||||
{
|
||||
// Add the removed value
|
||||
constant.add(dcv);
|
||||
complete.add(dcv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new mapped Collection
|
||||
*
|
||||
* @param c The new mapped Collection
|
||||
*/
|
||||
public void registerNewMappedCollection(Collection c)
|
||||
{
|
||||
// Add the new owning Collection
|
||||
newMappedCollections.add(c);
|
||||
empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an old mapped Collection
|
||||
*
|
||||
* @param c The old mapped Collection
|
||||
*/
|
||||
public void registerOldMappedCollection(Collection c)
|
||||
{
|
||||
// Add the old owning Collection (if it isn't there already, or is an old collection)
|
||||
boolean found = false;
|
||||
|
||||
if ((this.getOldOwningCollection() != null) &&
|
||||
(this.getOldOwningCollection().getHandle().equals(c.getHandle())))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
|
||||
for (Collection collection : oldMappedCollections)
|
||||
{
|
||||
if (collection.getHandle().equals(c.getHandle()))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
oldMappedCollections.add(c);
|
||||
empty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a change to the owning collection
|
||||
*
|
||||
* @param oldC The old owning collection
|
||||
* @param newC The new owning collection
|
||||
*/
|
||||
public void changeOwningCollection(Collection oldC, Collection newC)
|
||||
{
|
||||
// Store the old owning collection
|
||||
oldOwningCollection = oldC;
|
||||
|
||||
// Store the new owning collection
|
||||
newOwningCollection = newC;
|
||||
empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the owning collection of an item
|
||||
*
|
||||
* @param newC The new owning collection
|
||||
*/
|
||||
public void setOwningCollection(Collection newC)
|
||||
{
|
||||
// Store the new owning collection
|
||||
newOwningCollection = newC;
|
||||
//empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DSpace Item that these changes are applicable to.
|
||||
*
|
||||
* @return The item
|
||||
*/
|
||||
public Item getItem()
|
||||
{
|
||||
// Return the item
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of elements and their values that have been added.
|
||||
*
|
||||
* @return the list of elements and their values that have been added.
|
||||
*/
|
||||
public List<DCValue> getAdds()
|
||||
{
|
||||
// Return the array
|
||||
return adds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of elements and their values that have been removed.
|
||||
*
|
||||
* @return the list of elements and their values that have been removed.
|
||||
*/
|
||||
public List<DCValue> getRemoves()
|
||||
{
|
||||
// Return the array
|
||||
return removes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of unchanged values
|
||||
*
|
||||
* @return the list of unchanged values
|
||||
*/
|
||||
public List<DCValue> getConstant()
|
||||
{
|
||||
// Return the array
|
||||
return constant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of all values
|
||||
*
|
||||
* @return the list of all values
|
||||
*/
|
||||
public List<DCValue> getComplete()
|
||||
{
|
||||
// Return the array
|
||||
return complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of new mapped Collections
|
||||
*
|
||||
* @return the list of new mapped collections
|
||||
*/
|
||||
public List<Collection> getNewMappedCollections()
|
||||
{
|
||||
// Return the array
|
||||
return newMappedCollections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of old mapped Collections
|
||||
*
|
||||
* @return the list of old mapped collections
|
||||
*/
|
||||
public List<Collection> getOldMappedCollections()
|
||||
{
|
||||
// Return the array
|
||||
return oldMappedCollections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the old owning collection
|
||||
*
|
||||
* @return the old owning collection
|
||||
*/
|
||||
public Collection getOldOwningCollection()
|
||||
{
|
||||
// Return the old owning collection
|
||||
return oldOwningCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the new owning collection
|
||||
*
|
||||
* @return the new owning collection
|
||||
*/
|
||||
public Collection getNewOwningCollection()
|
||||
{
|
||||
// Return the new owning collection
|
||||
return newOwningCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this change object represent a new item?
|
||||
*
|
||||
* @return Whether or not this is for a new item
|
||||
*/
|
||||
public boolean isNewItem()
|
||||
{
|
||||
// Return the new item status
|
||||
return newItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Have any changes actually been recorded, or is this empty?
|
||||
*
|
||||
* @return Whether or not changes have been made
|
||||
*/
|
||||
public boolean hasChanges()
|
||||
{
|
||||
return !empty;
|
||||
}
|
||||
/**
|
||||
* 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.app.bulkedit;
|
||||
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.Collection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class to store changes to item that may occur during a batch edit.
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public class BulkEditChange
|
||||
{
|
||||
/** The item these changes relate to */
|
||||
private Item item;
|
||||
|
||||
/** The List of hashtables with the new elements */
|
||||
private List<DCValue> adds;
|
||||
|
||||
/** The List of hashtables with the removed elements */
|
||||
private List<DCValue> removes;
|
||||
|
||||
/** The List of hashtables with the unchanged elements */
|
||||
private List<DCValue> constant;
|
||||
|
||||
/** The List of the complete set of new values (constant + adds) */
|
||||
private List<DCValue> complete;
|
||||
|
||||
/** The list of old collections the item used to be mapped to */
|
||||
private List<Collection> oldMappedCollections;
|
||||
|
||||
/** The list of new collections the item has been mapped into */
|
||||
private List<Collection> newMappedCollections;
|
||||
|
||||
/** The old owning collection */
|
||||
private Collection oldOwningCollection;
|
||||
|
||||
/** The new owning collection */
|
||||
private Collection newOwningCollection;
|
||||
|
||||
/** Is this a new item */
|
||||
private boolean newItem;
|
||||
|
||||
/** Have any changes actually been made? */
|
||||
private boolean empty;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise a change holder for a new item
|
||||
*/
|
||||
public BulkEditChange()
|
||||
{
|
||||
// Set the item to be null
|
||||
item = null;
|
||||
newItem = true;
|
||||
empty = true;
|
||||
oldOwningCollection = null;
|
||||
newOwningCollection = null;
|
||||
|
||||
// Initialise the arrays
|
||||
adds = new ArrayList<DCValue>();
|
||||
removes = new ArrayList<DCValue>();
|
||||
constant = new ArrayList<DCValue>();
|
||||
complete = new ArrayList<DCValue>();
|
||||
oldMappedCollections = new ArrayList<Collection>();
|
||||
newMappedCollections = new ArrayList<Collection>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise a new change holder for an existing item
|
||||
*
|
||||
* @param i The Item to store
|
||||
*/
|
||||
public BulkEditChange(Item i)
|
||||
{
|
||||
// Store the item
|
||||
item = i;
|
||||
newItem = false;
|
||||
empty = true;
|
||||
|
||||
// Initialise the arrays
|
||||
adds = new ArrayList<DCValue>();
|
||||
removes = new ArrayList<DCValue>();
|
||||
constant = new ArrayList<DCValue>();
|
||||
complete = new ArrayList<DCValue>();
|
||||
oldMappedCollections = new ArrayList<Collection>();
|
||||
newMappedCollections = new ArrayList<Collection>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the item - used when a new item is created
|
||||
*
|
||||
* @param i The item
|
||||
*/
|
||||
public void setItem(Item i)
|
||||
{
|
||||
// Store the item
|
||||
item = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an added metadata value
|
||||
*
|
||||
* @param dcv The value to add
|
||||
*/
|
||||
public void registerAdd(DCValue dcv)
|
||||
{
|
||||
// Add the added value
|
||||
adds.add(dcv);
|
||||
complete.add(dcv);
|
||||
empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a removed metadata value
|
||||
*
|
||||
* @param dcv The value to remove
|
||||
*/
|
||||
public void registerRemove(DCValue dcv)
|
||||
{
|
||||
// Add the removed value
|
||||
removes.add(dcv);
|
||||
empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an unchanged metadata value
|
||||
*
|
||||
* @param dcv The value to keep unchanged
|
||||
*/
|
||||
public void registerConstant(DCValue dcv)
|
||||
{
|
||||
// Add the removed value
|
||||
constant.add(dcv);
|
||||
complete.add(dcv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new mapped Collection
|
||||
*
|
||||
* @param c The new mapped Collection
|
||||
*/
|
||||
public void registerNewMappedCollection(Collection c)
|
||||
{
|
||||
// Add the new owning Collection
|
||||
newMappedCollections.add(c);
|
||||
empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an old mapped Collection
|
||||
*
|
||||
* @param c The old mapped Collection
|
||||
*/
|
||||
public void registerOldMappedCollection(Collection c)
|
||||
{
|
||||
// Add the old owning Collection (if it isn't there already, or is an old collection)
|
||||
boolean found = false;
|
||||
|
||||
if ((this.getOldOwningCollection() != null) &&
|
||||
(this.getOldOwningCollection().getHandle().equals(c.getHandle())))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
|
||||
for (Collection collection : oldMappedCollections)
|
||||
{
|
||||
if (collection.getHandle().equals(c.getHandle()))
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
oldMappedCollections.add(c);
|
||||
empty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a change to the owning collection
|
||||
*
|
||||
* @param oldC The old owning collection
|
||||
* @param newC The new owning collection
|
||||
*/
|
||||
public void changeOwningCollection(Collection oldC, Collection newC)
|
||||
{
|
||||
// Store the old owning collection
|
||||
oldOwningCollection = oldC;
|
||||
|
||||
// Store the new owning collection
|
||||
newOwningCollection = newC;
|
||||
empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the owning collection of an item
|
||||
*
|
||||
* @param newC The new owning collection
|
||||
*/
|
||||
public void setOwningCollection(Collection newC)
|
||||
{
|
||||
// Store the new owning collection
|
||||
newOwningCollection = newC;
|
||||
//empty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DSpace Item that these changes are applicable to.
|
||||
*
|
||||
* @return The item
|
||||
*/
|
||||
public Item getItem()
|
||||
{
|
||||
// Return the item
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of elements and their values that have been added.
|
||||
*
|
||||
* @return the list of elements and their values that have been added.
|
||||
*/
|
||||
public List<DCValue> getAdds()
|
||||
{
|
||||
// Return the array
|
||||
return adds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of elements and their values that have been removed.
|
||||
*
|
||||
* @return the list of elements and their values that have been removed.
|
||||
*/
|
||||
public List<DCValue> getRemoves()
|
||||
{
|
||||
// Return the array
|
||||
return removes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of unchanged values
|
||||
*
|
||||
* @return the list of unchanged values
|
||||
*/
|
||||
public List<DCValue> getConstant()
|
||||
{
|
||||
// Return the array
|
||||
return constant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of all values
|
||||
*
|
||||
* @return the list of all values
|
||||
*/
|
||||
public List<DCValue> getComplete()
|
||||
{
|
||||
// Return the array
|
||||
return complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of new mapped Collections
|
||||
*
|
||||
* @return the list of new mapped collections
|
||||
*/
|
||||
public List<Collection> getNewMappedCollections()
|
||||
{
|
||||
// Return the array
|
||||
return newMappedCollections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of old mapped Collections
|
||||
*
|
||||
* @return the list of old mapped collections
|
||||
*/
|
||||
public List<Collection> getOldMappedCollections()
|
||||
{
|
||||
// Return the array
|
||||
return oldMappedCollections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the old owning collection
|
||||
*
|
||||
* @return the old owning collection
|
||||
*/
|
||||
public Collection getOldOwningCollection()
|
||||
{
|
||||
// Return the old owning collection
|
||||
return oldOwningCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the new owning collection
|
||||
*
|
||||
* @return the new owning collection
|
||||
*/
|
||||
public Collection getNewOwningCollection()
|
||||
{
|
||||
// Return the new owning collection
|
||||
return newOwningCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this change object represent a new item?
|
||||
*
|
||||
* @return Whether or not this is for a new item
|
||||
*/
|
||||
public boolean isNewItem()
|
||||
{
|
||||
// Return the new item status
|
||||
return newItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Have any changes actually been recorded, or is this empty?
|
||||
*
|
||||
* @return Whether or not changes have been made
|
||||
*/
|
||||
public boolean hasChanges()
|
||||
{
|
||||
return !empty;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,176 +1,176 @@
|
||||
/**
|
||||
* 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.app.bulkedit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Utility class to store a line from a CSV file
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public class DSpaceCSVLine
|
||||
{
|
||||
/** The item id of the item represented by this line. -1 is for a new item */
|
||||
private int id;
|
||||
|
||||
/** The elements in this line in a hashtable, keyed by the metadata type */
|
||||
private Map<String, ArrayList> items;
|
||||
|
||||
/**
|
||||
* Create a new CSV line
|
||||
*
|
||||
* @param id The item ID of the line
|
||||
*/
|
||||
public DSpaceCSVLine(int itemId)
|
||||
{
|
||||
// Store the ID + separator, and initialise the hashtable
|
||||
this.id = itemId;
|
||||
items = new HashMap<String, ArrayList>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CSV line for a new item
|
||||
*/
|
||||
public DSpaceCSVLine()
|
||||
{
|
||||
// Set the ID to be -1, and initialise the hashtable
|
||||
this.id = -1;
|
||||
this.items = new HashMap<String, ArrayList>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item ID that this line represents
|
||||
*
|
||||
* @return The item ID
|
||||
*/
|
||||
public int getID()
|
||||
{
|
||||
// Return the ID
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new metadata value to this line
|
||||
*
|
||||
* @param key The metadata key (e.g. dc.contributor.author)
|
||||
* @param value The metadata value
|
||||
*/
|
||||
public void add(String key, String value)
|
||||
{
|
||||
// Create the array list if we need to
|
||||
if (items.get(key) == null)
|
||||
{
|
||||
items.put(key, new ArrayList<String>());
|
||||
}
|
||||
|
||||
// Store the item if it is not null
|
||||
if (value != null)
|
||||
{
|
||||
items.get(key).add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the values that match the given metadata key. Will be null if none exist.
|
||||
*
|
||||
* @param key The metadata key
|
||||
* @return All the elements that match
|
||||
*/
|
||||
public List<String> get(String key)
|
||||
{
|
||||
// Return any relevant values
|
||||
return items.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the metadata keys that are represented in this line
|
||||
*
|
||||
* @return An enumeration of all the keys
|
||||
*/
|
||||
public Set<String> keys()
|
||||
{
|
||||
// Return the keys
|
||||
return items.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write this line out as a CSV formatted string, in the order given by the headings provided
|
||||
*
|
||||
* @param headings The headings which define the order the elements must be presented in
|
||||
* @return The CSV formatted String
|
||||
*/
|
||||
protected String toCSV(List<String> headings)
|
||||
{
|
||||
StringBuilder bits = new StringBuilder();
|
||||
|
||||
// Add the id
|
||||
bits.append("\"").append(id).append("\"").append(DSpaceCSV.fieldSeparator);
|
||||
bits.append(valueToCSV(items.get("collection")));
|
||||
|
||||
// Add the rest of the elements
|
||||
for (String heading : headings)
|
||||
{
|
||||
bits.append(DSpaceCSV.fieldSeparator);
|
||||
List<String> values = items.get(heading);
|
||||
if (values != null && !"collection".equals(heading))
|
||||
{
|
||||
bits.append(valueToCSV(values));
|
||||
}
|
||||
}
|
||||
|
||||
return bits.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to create a CSV formatted String joining a given set of elements
|
||||
*
|
||||
* @param values The values to create the string from
|
||||
* @return The line as a CSV formatted String
|
||||
*/
|
||||
protected String valueToCSV(List<String> values)
|
||||
{
|
||||
// Check there is some content
|
||||
if (values == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get on with the work
|
||||
String s;
|
||||
if (values.size() == 1)
|
||||
{
|
||||
s = values.get(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Concatenate any fields together
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
for (String value : values)
|
||||
{
|
||||
if (str.length() > 0)
|
||||
{
|
||||
str.append(DSpaceCSV.valueSeparator);
|
||||
}
|
||||
|
||||
str.append(value);
|
||||
}
|
||||
|
||||
s = str.toString();
|
||||
}
|
||||
|
||||
// Replace internal quotes with two sets of quotes
|
||||
return "\"" + s.replaceAll("\"", "\"\"") + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.app.bulkedit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Utility class to store a line from a CSV file
|
||||
*
|
||||
* @author Stuart Lewis
|
||||
*/
|
||||
public class DSpaceCSVLine
|
||||
{
|
||||
/** The item id of the item represented by this line. -1 is for a new item */
|
||||
private int id;
|
||||
|
||||
/** The elements in this line in a hashtable, keyed by the metadata type */
|
||||
private Map<String, ArrayList> items;
|
||||
|
||||
/**
|
||||
* Create a new CSV line
|
||||
*
|
||||
* @param id The item ID of the line
|
||||
*/
|
||||
public DSpaceCSVLine(int itemId)
|
||||
{
|
||||
// Store the ID + separator, and initialise the hashtable
|
||||
this.id = itemId;
|
||||
items = new HashMap<String, ArrayList>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CSV line for a new item
|
||||
*/
|
||||
public DSpaceCSVLine()
|
||||
{
|
||||
// Set the ID to be -1, and initialise the hashtable
|
||||
this.id = -1;
|
||||
this.items = new HashMap<String, ArrayList>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item ID that this line represents
|
||||
*
|
||||
* @return The item ID
|
||||
*/
|
||||
public int getID()
|
||||
{
|
||||
// Return the ID
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new metadata value to this line
|
||||
*
|
||||
* @param key The metadata key (e.g. dc.contributor.author)
|
||||
* @param value The metadata value
|
||||
*/
|
||||
public void add(String key, String value)
|
||||
{
|
||||
// Create the array list if we need to
|
||||
if (items.get(key) == null)
|
||||
{
|
||||
items.put(key, new ArrayList<String>());
|
||||
}
|
||||
|
||||
// Store the item if it is not null
|
||||
if (value != null)
|
||||
{
|
||||
items.get(key).add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the values that match the given metadata key. Will be null if none exist.
|
||||
*
|
||||
* @param key The metadata key
|
||||
* @return All the elements that match
|
||||
*/
|
||||
public List<String> get(String key)
|
||||
{
|
||||
// Return any relevant values
|
||||
return items.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the metadata keys that are represented in this line
|
||||
*
|
||||
* @return An enumeration of all the keys
|
||||
*/
|
||||
public Set<String> keys()
|
||||
{
|
||||
// Return the keys
|
||||
return items.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write this line out as a CSV formatted string, in the order given by the headings provided
|
||||
*
|
||||
* @param headings The headings which define the order the elements must be presented in
|
||||
* @return The CSV formatted String
|
||||
*/
|
||||
protected String toCSV(List<String> headings)
|
||||
{
|
||||
StringBuilder bits = new StringBuilder();
|
||||
|
||||
// Add the id
|
||||
bits.append("\"").append(id).append("\"").append(DSpaceCSV.fieldSeparator);
|
||||
bits.append(valueToCSV(items.get("collection")));
|
||||
|
||||
// Add the rest of the elements
|
||||
for (String heading : headings)
|
||||
{
|
||||
bits.append(DSpaceCSV.fieldSeparator);
|
||||
List<String> values = items.get(heading);
|
||||
if (values != null && !"collection".equals(heading))
|
||||
{
|
||||
bits.append(valueToCSV(values));
|
||||
}
|
||||
}
|
||||
|
||||
return bits.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to create a CSV formatted String joining a given set of elements
|
||||
*
|
||||
* @param values The values to create the string from
|
||||
* @return The line as a CSV formatted String
|
||||
*/
|
||||
protected String valueToCSV(List<String> values)
|
||||
{
|
||||
// Check there is some content
|
||||
if (values == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get on with the work
|
||||
String s;
|
||||
if (values.size() == 1)
|
||||
{
|
||||
s = values.get(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Concatenate any fields together
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
for (String value : values)
|
||||
{
|
||||
if (str.length() > 0)
|
||||
{
|
||||
str.append(DSpaceCSV.valueSeparator);
|
||||
}
|
||||
|
||||
str.append(value);
|
||||
}
|
||||
|
||||
s = str.toString();
|
||||
}
|
||||
|
||||
// Replace internal quotes with two sets of quotes
|
||||
return "\"" + s.replaceAll("\"", "\"\"") + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -494,7 +494,7 @@ public class Item extends DSpaceObject
|
||||
int i = 0;
|
||||
while(dcf.hasMoreTokens())
|
||||
{
|
||||
tokens[i] = dcf.nextToken().toLowerCase().trim();
|
||||
tokens[i] = dcf.nextToken().trim();
|
||||
i++;
|
||||
}
|
||||
String schema = tokens[0];
|
||||
@@ -908,7 +908,8 @@ public class Item extends DSpaceObject
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!schema.equals(Item.ANY))
|
||||
|
||||
if (!schema.equals(Item.ANY))
|
||||
{
|
||||
if (dcv.schema != null && !dcv.schema.equals(schema))
|
||||
{
|
||||
|
@@ -1,147 +1,147 @@
|
||||
/**
|
||||
* 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.content;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.license.FormattableArgument;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
|
||||
/**
|
||||
* Utility class to manage generation and storing of the license text that the
|
||||
* submitter has to grant/granted for archiving the item
|
||||
*
|
||||
* @author bollini
|
||||
*
|
||||
*/
|
||||
public class LicenseUtils
|
||||
{
|
||||
/**
|
||||
* Return the text of the license that the user has granted/must grant
|
||||
* before for submit the item. The license text is build using the template
|
||||
* defined for the collection if any or the wide site configuration. In the
|
||||
* license text the following substitution can be used. {0} the eperson
|
||||
* firstname<br>
|
||||
* {1} the eperson lastname<br>
|
||||
* {2} the eperson email<br>
|
||||
* {3} the current date<br>
|
||||
* {4} the collection object that will be formatted using the appropriate
|
||||
* LicenseArgumentFormatter plugin (if defined)<br>
|
||||
* {5} the item object that will be formatted using the appropriate
|
||||
* LicenseArgumentFormatter plugin (if defined)<br>
|
||||
* {6} the eperson object that will be formatted using the appropriate
|
||||
* LicenseArgumentFormatter plugin (if defined)<br>
|
||||
* {x} any addition argument supplied wrapped in the
|
||||
* LicenseArgumentFormatter based on his type (map key)
|
||||
*
|
||||
* @see LicenseArgumentFormatter
|
||||
* @param locale
|
||||
* @param collection
|
||||
* @param item
|
||||
* @param eperson
|
||||
* @param additionalInfo
|
||||
* @return the license text obtained substituting the provided argument in
|
||||
* the license template
|
||||
*/
|
||||
public static String getLicenseText(Locale locale, Collection collection,
|
||||
Item item, EPerson eperson, Map<String, Object> additionalInfo)
|
||||
{
|
||||
Formatter formatter = new Formatter(locale);
|
||||
|
||||
// EPerson firstname, lastname, email and the current date
|
||||
// will be available as separate arguments to make more simple produce
|
||||
// "tradition" text license
|
||||
// collection, item and eperson object will be also available
|
||||
int numArgs = 7 + (additionalInfo != null ? additionalInfo.size() : 0);
|
||||
Object[] args = new Object[numArgs];
|
||||
args[0] = eperson.getFirstName();
|
||||
args[1] = eperson.getLastName();
|
||||
args[2] = eperson.getEmail();
|
||||
args[3] = new java.util.Date();
|
||||
args[4] = new FormattableArgument("collection", collection);
|
||||
args[5] = new FormattableArgument("item", item);
|
||||
args[6] = new FormattableArgument("eperson", eperson);
|
||||
|
||||
if (additionalInfo != null)
|
||||
{
|
||||
int i = 7; // Start is next index after previous args
|
||||
for (Map.Entry<String, Object> info : additionalInfo.entrySet())
|
||||
{
|
||||
args[i] = new FormattableArgument(info.getKey(), info.getValue());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
String licenseTemplate = collection.getLicense();
|
||||
|
||||
return formatter.format(licenseTemplate, args).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method if no additional arguments has need to be supplied to the
|
||||
* license template. (i.e. call the full getLicenseText supplying
|
||||
* <code>null</code> for the additionalInfo argument)
|
||||
*
|
||||
* @param locale
|
||||
* @param collection
|
||||
* @param item
|
||||
* @param eperson
|
||||
* @return
|
||||
*/
|
||||
public static String getLicenseText(Locale locale, Collection collection,
|
||||
Item item, EPerson eperson)
|
||||
{
|
||||
return getLicenseText(locale, collection, item, eperson, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a copy of the license a user granted in the item.
|
||||
*
|
||||
* @param context
|
||||
* the dspace context
|
||||
* @param item
|
||||
* the item object of the license
|
||||
* @param licenseText
|
||||
* the license the user granted
|
||||
* @throws SQLException
|
||||
* @throws IOException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
public static void grantLicense(Context context, Item item,
|
||||
String licenseText) throws SQLException, IOException,
|
||||
AuthorizeException
|
||||
{
|
||||
// Put together text to store
|
||||
// String licenseText = "License granted by " + eperson.getFullName()
|
||||
// + " (" + eperson.getEmail() + ") on "
|
||||
// + DCDate.getCurrent().toString() + " (GMT):\n\n" + license;
|
||||
|
||||
// Store text as a bitstream
|
||||
byte[] licenseBytes = licenseText.getBytes();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(licenseBytes);
|
||||
Bitstream b = item.createSingleBitstream(bais, "LICENSE");
|
||||
|
||||
// Now set the format and name of the bitstream
|
||||
b.setName("license.txt");
|
||||
b.setSource("Written by org.dspace.content.LicenseUtils");
|
||||
|
||||
// Find the License format
|
||||
BitstreamFormat bf = BitstreamFormat.findByShortDescription(context,
|
||||
"License");
|
||||
b.setFormat(bf);
|
||||
|
||||
b.update();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.license.FormattableArgument;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
|
||||
/**
|
||||
* Utility class to manage generation and storing of the license text that the
|
||||
* submitter has to grant/granted for archiving the item
|
||||
*
|
||||
* @author bollini
|
||||
*
|
||||
*/
|
||||
public class LicenseUtils
|
||||
{
|
||||
/**
|
||||
* Return the text of the license that the user has granted/must grant
|
||||
* before for submit the item. The license text is build using the template
|
||||
* defined for the collection if any or the wide site configuration. In the
|
||||
* license text the following substitution can be used. {0} the eperson
|
||||
* firstname<br>
|
||||
* {1} the eperson lastname<br>
|
||||
* {2} the eperson email<br>
|
||||
* {3} the current date<br>
|
||||
* {4} the collection object that will be formatted using the appropriate
|
||||
* LicenseArgumentFormatter plugin (if defined)<br>
|
||||
* {5} the item object that will be formatted using the appropriate
|
||||
* LicenseArgumentFormatter plugin (if defined)<br>
|
||||
* {6} the eperson object that will be formatted using the appropriate
|
||||
* LicenseArgumentFormatter plugin (if defined)<br>
|
||||
* {x} any addition argument supplied wrapped in the
|
||||
* LicenseArgumentFormatter based on his type (map key)
|
||||
*
|
||||
* @see LicenseArgumentFormatter
|
||||
* @param locale
|
||||
* @param collection
|
||||
* @param item
|
||||
* @param eperson
|
||||
* @param additionalInfo
|
||||
* @return the license text obtained substituting the provided argument in
|
||||
* the license template
|
||||
*/
|
||||
public static String getLicenseText(Locale locale, Collection collection,
|
||||
Item item, EPerson eperson, Map<String, Object> additionalInfo)
|
||||
{
|
||||
Formatter formatter = new Formatter(locale);
|
||||
|
||||
// EPerson firstname, lastname, email and the current date
|
||||
// will be available as separate arguments to make more simple produce
|
||||
// "tradition" text license
|
||||
// collection, item and eperson object will be also available
|
||||
int numArgs = 7 + (additionalInfo != null ? additionalInfo.size() : 0);
|
||||
Object[] args = new Object[numArgs];
|
||||
args[0] = eperson.getFirstName();
|
||||
args[1] = eperson.getLastName();
|
||||
args[2] = eperson.getEmail();
|
||||
args[3] = new java.util.Date();
|
||||
args[4] = new FormattableArgument("collection", collection);
|
||||
args[5] = new FormattableArgument("item", item);
|
||||
args[6] = new FormattableArgument("eperson", eperson);
|
||||
|
||||
if (additionalInfo != null)
|
||||
{
|
||||
int i = 7; // Start is next index after previous args
|
||||
for (Map.Entry<String, Object> info : additionalInfo.entrySet())
|
||||
{
|
||||
args[i] = new FormattableArgument(info.getKey(), info.getValue());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
String licenseTemplate = collection.getLicense();
|
||||
|
||||
return formatter.format(licenseTemplate, args).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method if no additional arguments has need to be supplied to the
|
||||
* license template. (i.e. call the full getLicenseText supplying
|
||||
* <code>null</code> for the additionalInfo argument)
|
||||
*
|
||||
* @param locale
|
||||
* @param collection
|
||||
* @param item
|
||||
* @param eperson
|
||||
* @return
|
||||
*/
|
||||
public static String getLicenseText(Locale locale, Collection collection,
|
||||
Item item, EPerson eperson)
|
||||
{
|
||||
return getLicenseText(locale, collection, item, eperson, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a copy of the license a user granted in the item.
|
||||
*
|
||||
* @param context
|
||||
* the dspace context
|
||||
* @param item
|
||||
* the item object of the license
|
||||
* @param licenseText
|
||||
* the license the user granted
|
||||
* @throws SQLException
|
||||
* @throws IOException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
public static void grantLicense(Context context, Item item,
|
||||
String licenseText) throws SQLException, IOException,
|
||||
AuthorizeException
|
||||
{
|
||||
// Put together text to store
|
||||
// String licenseText = "License granted by " + eperson.getFullName()
|
||||
// + " (" + eperson.getEmail() + ") on "
|
||||
// + DCDate.getCurrent().toString() + " (GMT):\n\n" + license;
|
||||
|
||||
// Store text as a bitstream
|
||||
byte[] licenseBytes = licenseText.getBytes();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(licenseBytes);
|
||||
Bitstream b = item.createSingleBitstream(bais, "LICENSE");
|
||||
|
||||
// Now set the format and name of the bitstream
|
||||
b.setName("license.txt");
|
||||
b.setSource("Written by org.dspace.content.LicenseUtils");
|
||||
|
||||
// Find the License format
|
||||
BitstreamFormat bf = BitstreamFormat.findByShortDescription(context,
|
||||
"License");
|
||||
b.setFormat(bf);
|
||||
|
||||
b.update();
|
||||
}
|
||||
}
|
||||
|
@@ -354,6 +354,7 @@ public class MetadataSchema
|
||||
"metadata_schema_id=" + getSchemaID()));
|
||||
|
||||
DatabaseManager.delete(context, row);
|
||||
decache();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -362,6 +362,34 @@ public class WorkspaceItem implements InProgressSubmission
|
||||
return wsItems.toArray(new WorkspaceItem[wsItems.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a particular item is currently still in a user's Workspace.
|
||||
* If so, its WorkspaceItem is returned. If not, null is returned
|
||||
*
|
||||
* @param context
|
||||
* the context object
|
||||
* @param i
|
||||
* the item
|
||||
*
|
||||
* @return workflow item corresponding to the item, or null
|
||||
*/
|
||||
public static WorkspaceItem findByItem(Context context, Item i)
|
||||
throws SQLException
|
||||
{
|
||||
// Look for the unique workspaceitem entry where 'item_id' references this item
|
||||
TableRow row = DatabaseManager.findByUnique(context, "workspaceitem", "item_id", i.getID());
|
||||
|
||||
if (row == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new WorkspaceItem(context, row);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all workspace items in the whole system
|
||||
*
|
||||
|
@@ -31,6 +31,7 @@ public interface ChoiceAuthority
|
||||
* defaultSelected index in the Choices instance to the choice, if any,
|
||||
* that matches the value.
|
||||
*
|
||||
* @param field being matched for
|
||||
* @param text user's value to match
|
||||
* @param collection database ID of Collection for context (owner of Item)
|
||||
* @param start choice at which to start, 0 is first.
|
||||
@@ -38,7 +39,7 @@ public interface ChoiceAuthority
|
||||
* @param locale explicit localization key if available, or null
|
||||
* @return a Choices object (never null).
|
||||
*/
|
||||
public Choices getMatches(String text, int collection, int start, int limit, String locale);
|
||||
public Choices getMatches(String field, String text, int collection, int start, int limit, String locale);
|
||||
|
||||
/**
|
||||
* Get the single "best" match (if any) of a value in the authority
|
||||
@@ -49,12 +50,13 @@ public interface ChoiceAuthority
|
||||
* This call is typically used in non-interactive metadata ingest
|
||||
* where there is no interactive agent to choose from among options.
|
||||
*
|
||||
* @param field being matched for
|
||||
* @param text user's value to match
|
||||
* @param collection database ID of Collection for context (owner of Item)
|
||||
* @param locale explicit localization key if available, or null
|
||||
* @return a Choices object (never null) with 1 or 0 values.
|
||||
*/
|
||||
public Choices getBestMatch(String text, int collection, String locale);
|
||||
public Choices getBestMatch(String field, String text, int collection, String locale);
|
||||
|
||||
/**
|
||||
* Get the canonical user-visible "label" (i.e. short descriptive text)
|
||||
@@ -64,9 +66,10 @@ public interface ChoiceAuthority
|
||||
* This may get called many times while populating a Web page so it should
|
||||
* be implemented as efficiently as possible.
|
||||
*
|
||||
* @param field being matched for
|
||||
* @param key authority key known to this authority.
|
||||
* @param locale explicit localization key if available, or null
|
||||
* @return descriptive label - should always return something, never null.
|
||||
*/
|
||||
public String getLabel(String key, String locale);
|
||||
public String getLabel(String field, String key, String locale);
|
||||
}
|
||||
|
@@ -153,7 +153,7 @@ public final class ChoiceAuthorityManager
|
||||
* Wrapper that calls getMatches method of the plugin corresponding to
|
||||
* the metadata field defined by schema,element,qualifier.
|
||||
*
|
||||
* @see ChoiceAuthority#getMatches(String, int, int, int, String)
|
||||
* @see ChoiceAuthority#getMatches(String, String, int, int, int, String)
|
||||
* @param schema schema of metadata field
|
||||
* @param element element of metadata field
|
||||
* @param qualifier qualifier of metadata field
|
||||
@@ -175,7 +175,7 @@ public final class ChoiceAuthorityManager
|
||||
* Wrapper calls getMatches method of the plugin corresponding to
|
||||
* the metadata field defined by single field key.
|
||||
*
|
||||
* @see ChoiceAuthority#getMatches(String, int, int, int, String)
|
||||
* @see ChoiceAuthority#getMatches(String, String, int, int, int, String)
|
||||
* @param fieldKey single string identifying metadata field
|
||||
* @param query user's value to match
|
||||
* @param collection database ID of Collection for context (owner of Item)
|
||||
@@ -194,14 +194,14 @@ public final class ChoiceAuthorityManager
|
||||
"No choices plugin was configured for field \"" + fieldKey
|
||||
+ "\".");
|
||||
}
|
||||
return ma.getMatches(query, collection, start, limit, locale);
|
||||
return ma.getMatches(fieldKey, query, collection, start, limit, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper that calls getBestMatch method of the plugin corresponding to
|
||||
* the metadata field defined by single field key.
|
||||
*
|
||||
* @see ChoiceAuthority#getBestMatch(String, int, String)
|
||||
* @see ChoiceAuthority#getBestMatch(String, String, int, String)
|
||||
* @param fieldKey single string identifying metadata field
|
||||
* @param query user's value to match
|
||||
* @param collection database ID of Collection for context (owner of Item)
|
||||
@@ -218,7 +218,7 @@ public final class ChoiceAuthorityManager
|
||||
"No choices plugin was configured for field \"" + fieldKey
|
||||
+ "\".");
|
||||
}
|
||||
return ma.getBestMatch(query, collection, locale);
|
||||
return ma.getBestMatch(fieldKey, query, collection, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,7 +242,7 @@ public final class ChoiceAuthorityManager
|
||||
{
|
||||
throw new IllegalArgumentException("No choices plugin was configured for field \"" + fieldKey + "\".");
|
||||
}
|
||||
return ma.getLabel(authKey, locale);
|
||||
return ma.getLabel(fieldKey, authKey, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -117,7 +117,7 @@ public class DCInputAuthority extends SelfNamedPlugin implements ChoiceAuthority
|
||||
}
|
||||
|
||||
|
||||
public Choices getMatches(String query, int collection, int start, int limit, String locale)
|
||||
public Choices getMatches(String field, String query, int collection, int start, int limit, String locale)
|
||||
{
|
||||
init();
|
||||
|
||||
@@ -134,7 +134,7 @@ public class DCInputAuthority extends SelfNamedPlugin implements ChoiceAuthority
|
||||
return new Choices(v, 0, v.length, Choices.CF_AMBIGUOUS, false, dflt);
|
||||
}
|
||||
|
||||
public Choices getBestMatch(String text, int collection, String locale)
|
||||
public Choices getBestMatch(String field, String text, int collection, String locale)
|
||||
{
|
||||
init();
|
||||
for (int i = 0; i < values.length; ++i)
|
||||
@@ -149,7 +149,7 @@ public class DCInputAuthority extends SelfNamedPlugin implements ChoiceAuthority
|
||||
return new Choices(Choices.CF_NOTFOUND);
|
||||
}
|
||||
|
||||
public String getLabel(String key, String locale)
|
||||
public String getLabel(String field, String key, String locale)
|
||||
{
|
||||
init();
|
||||
return labels[Integer.parseInt(key)];
|
||||
|
@@ -154,7 +154,7 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Choic
|
||||
}
|
||||
}
|
||||
|
||||
public Choices getMatches(String text, int collection, int start, int limit, String locale)
|
||||
public Choices getMatches(String field, String text, int collection, int start, int limit, String locale)
|
||||
{
|
||||
init();
|
||||
log.debug("Getting matches for '" + text + "'");
|
||||
@@ -203,14 +203,14 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Choic
|
||||
return new Choices(choices, 0, choices.length, Choices.CF_AMBIGUOUS, false);
|
||||
}
|
||||
|
||||
public Choices getBestMatch(String text, int collection, String locale)
|
||||
public Choices getBestMatch(String field, String text, int collection, String locale)
|
||||
{
|
||||
init();
|
||||
log.debug("Getting best match for '" + text + "'");
|
||||
return getMatches(text, collection, 0, 2, locale);
|
||||
return getMatches(field, text, collection, 0, 2, locale);
|
||||
}
|
||||
|
||||
public String getLabel(String key, String locale)
|
||||
public String getLabel(String field, String key, String locale)
|
||||
{
|
||||
init();
|
||||
String xpathExpression = String.format(idTemplate, key);
|
||||
@@ -222,4 +222,4 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Choic
|
||||
return("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -83,16 +83,16 @@ public class LCNameAuthority implements ChoiceAuthority
|
||||
}
|
||||
|
||||
// punt! this is a poor implementation..
|
||||
public Choices getBestMatch(String text, int collection, String locale)
|
||||
public Choices getBestMatch(String field, String text, int collection, String locale)
|
||||
{
|
||||
return getMatches(text, collection, 0, 2, locale);
|
||||
return getMatches(field, text, collection, 0, 2, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a proposed value against name authority records
|
||||
* Value is assumed to be in "Lastname, Firstname" format.
|
||||
*/
|
||||
public Choices getMatches(String text, int collection, int start, int limit, String locale)
|
||||
public Choices getMatches(String field, String text, int collection, int start, int limit, String locale)
|
||||
{
|
||||
Choices result = queryPerson(text, start, limit);
|
||||
if (result == null)
|
||||
@@ -105,7 +105,7 @@ public class LCNameAuthority implements ChoiceAuthority
|
||||
|
||||
// punt; supposed to get the canonical display form of a metadata authority key
|
||||
// XXX FIXME implement this with a query on the authority key, cache results
|
||||
public String getLabel(String key, String locale)
|
||||
public String getLabel(String field, String key, String locale)
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
@@ -52,4 +52,8 @@ public class SHERPARoMEOJournalTitle extends SHERPARoMEOProtocol
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Choices getMatches(String field, String text, int collection, int start, int limit, String locale) {
|
||||
return getMatches(text, collection, start, limit, locale);
|
||||
}
|
||||
}
|
||||
|
@@ -72,14 +72,14 @@ public abstract class SHERPARoMEOProtocol implements ChoiceAuthority
|
||||
// this implements the specific RoMEO API args and XML tag naming
|
||||
public abstract Choices getMatches(String text, int collection, int start, int limit, String locale);
|
||||
|
||||
public Choices getBestMatch(String text, int collection, String locale)
|
||||
public Choices getBestMatch(String field, String text, int collection, String locale)
|
||||
{
|
||||
return getMatches(text, collection, 0, 2, locale);
|
||||
return getMatches(field, text, collection, 0, 2, locale);
|
||||
}
|
||||
|
||||
// XXX FIXME just punt, returning value, never got around to
|
||||
// implementing a reverse query.
|
||||
public String getLabel(String key, String locale)
|
||||
public String getLabel(String field, String key, String locale)
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
@@ -53,4 +53,9 @@ public class SHERPARoMEOPublisher extends SHERPARoMEOProtocol
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Choices getMatches(String field, String text, int collection, int start, int limit, String locale) {
|
||||
return getMatches(text, collection, start, limit, locale);
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ public class SampleAuthority implements ChoiceAuthority
|
||||
"Saturday"
|
||||
};
|
||||
|
||||
public Choices getMatches(String query, int collection, int start, int limit, String locale)
|
||||
public Choices getMatches(String field, String query, int collection, int start, int limit, String locale)
|
||||
{
|
||||
int dflt = -1;
|
||||
Choice v[] = new Choice[values.length];
|
||||
@@ -48,7 +48,7 @@ public class SampleAuthority implements ChoiceAuthority
|
||||
return new Choices(v, 0, v.length, Choices.CF_AMBIGUOUS, false, dflt);
|
||||
}
|
||||
|
||||
public Choices getBestMatch(String text, int collection, String locale)
|
||||
public Choices getBestMatch(String field, String text, int collection, String locale)
|
||||
{
|
||||
for (int i = 0; i < values.length; ++i)
|
||||
{
|
||||
@@ -62,7 +62,7 @@ public class SampleAuthority implements ChoiceAuthority
|
||||
return new Choices(Choices.CF_NOTFOUND);
|
||||
}
|
||||
|
||||
public String getLabel(String key, String locale)
|
||||
public String getLabel(String field, String key, String locale)
|
||||
{
|
||||
return labels[Integer.parseInt(key)];
|
||||
}
|
||||
|
@@ -1,174 +1,174 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Namespace;
|
||||
|
||||
/**
|
||||
* Crosswalk descriptive metadata to and from DIM (DSpace Intermediate
|
||||
* Metadata) format, strictly for the purpose of including a precise and
|
||||
* complete record of the DMD in an AIP. Although the DIM format was never
|
||||
* intended to be used outside of DSpace, it is admirably suited to
|
||||
* describing the exact state of the descriptive MD stored in the RDBMS.
|
||||
* All crosswalks to standard formats such as MODS and even DC are necessarily
|
||||
* "lossy" and inexact. Since the purpose of an AIP is to preserve and restore
|
||||
* the state of an object exactly, DIM is the preferred format for
|
||||
* recording its descriptive MD.
|
||||
* <p>
|
||||
* In order to allow external applications to make sense of DSpace AIPs for
|
||||
* preservation purposes, we recommend adding a parallel descriptive
|
||||
* metadata section in one of the preferred standard formats such as MODS
|
||||
* as well as the DIM.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class AIPDIMCrosswalk
|
||||
implements DisseminationCrosswalk, IngestionCrosswalk
|
||||
{
|
||||
/**
|
||||
* Get XML namespaces of the elements this crosswalk may return.
|
||||
* Returns the XML namespaces (as JDOM objects) of the root element.
|
||||
*
|
||||
* @return array of namespaces, which may be empty.
|
||||
*/
|
||||
public Namespace[] getNamespaces()
|
||||
{
|
||||
Namespace result[] = new Namespace[1];
|
||||
result[0] = XSLTCrosswalk.DIM_NS;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the XML Schema location(s) of the target metadata format.
|
||||
* Returns the string value of the <code>xsi:schemaLocation</code>
|
||||
* attribute that should be applied to the generated XML.
|
||||
* <p>
|
||||
* It may return the empty string if no schema is known, but crosswalk
|
||||
* authors are strongly encouraged to implement this call so their output
|
||||
* XML can be validated correctly.
|
||||
* @return SchemaLocation string, including URI namespace, followed by
|
||||
* whitespace and URI of XML schema document, or empty string if unknown.
|
||||
*/
|
||||
public String getSchemaLocation()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate: Can this disseminator crosswalk the given object.
|
||||
* Needed by OAI-PMH server implementation.
|
||||
*
|
||||
* @param dso dspace object, e.g. an <code>Item</code>.
|
||||
* @return true when disseminator is capable of producing metadata.
|
||||
*/
|
||||
public boolean canDisseminate(DSpaceObject dso)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate: Does this disseminator prefer to return a list of Elements,
|
||||
* rather than a single root Element?
|
||||
* <p>
|
||||
* Some metadata formats have an XML schema without a root element,
|
||||
* for example, the Dublin Core and Qualified Dublin Core formats.
|
||||
* This would be <code>true</code> for a crosswalk into QDC, since
|
||||
* it would "prefer" to return a list, since any root element it has
|
||||
* to produce would have to be part of a nonstandard schema. In
|
||||
* most cases your implementation will want to return
|
||||
* <code>false</code>
|
||||
*
|
||||
* @return true when disseminator prefers you call disseminateList().
|
||||
*/
|
||||
public boolean preferList()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute crosswalk, returning List of XML elements.
|
||||
* Returns a <code>List</code> of JDOM <code>Element</code> objects representing
|
||||
* the XML produced by the crosswalk. This is typically called when
|
||||
* a list of fields is desired, e.g. for embedding in a METS document
|
||||
* <code>xmlData</code> field.
|
||||
* <p>
|
||||
* When there are no results, an
|
||||
* empty list is returned, but never <code>null</code>.
|
||||
*
|
||||
* @param dso the DSpace Object whose metadata to export.
|
||||
* @return results of crosswalk as list of XML elements.
|
||||
*
|
||||
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
|
||||
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
|
||||
* @throws IOException I/O failure in services this calls
|
||||
* @throws SQLException Database failure in services this calls
|
||||
* @throws AuthorizeException current user not authorized for this operation.
|
||||
*/
|
||||
public List<Element> disseminateList(DSpaceObject dso)
|
||||
throws CrosswalkException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
Element dim = disseminateElement(dso);
|
||||
return dim.getChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute crosswalk, returning one XML root element as
|
||||
* a JDOM <code>Element</code> object.
|
||||
* This is typically the root element of a document.
|
||||
* <p>
|
||||
*
|
||||
* @param dso the DSpace Object whose metadata to export.
|
||||
* @return root Element of the target metadata, never <code>null</code>
|
||||
*
|
||||
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
|
||||
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
|
||||
* @throws IOException I/O failure in services this calls
|
||||
* @throws SQLException Database failure in services this calls
|
||||
* @throws AuthorizeException current user not authorized for this operation.
|
||||
*/
|
||||
public Element disseminateElement(DSpaceObject dso)
|
||||
throws CrosswalkException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
return XSLTDisseminationCrosswalk.createDIM(dso);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ingest a whole document. Build Document object around root element,
|
||||
* and feed that to the transformation, since it may get handled
|
||||
* differently than a List of metadata elements.
|
||||
*/
|
||||
public void ingest(Context context, DSpaceObject dso, Element root)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
ingest(context, dso, root.getChildren());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fields correspond directly to Item.addMetadata() calls so
|
||||
* they are simply executed.
|
||||
*/
|
||||
public void ingest(Context context, DSpaceObject dso, List<Element> dimList)
|
||||
throws CrosswalkException,
|
||||
IOException, SQLException, AuthorizeException
|
||||
{
|
||||
XSLTIngestionCrosswalk.ingestDIM(context, dso, dimList);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Namespace;
|
||||
|
||||
/**
|
||||
* Crosswalk descriptive metadata to and from DIM (DSpace Intermediate
|
||||
* Metadata) format, strictly for the purpose of including a precise and
|
||||
* complete record of the DMD in an AIP. Although the DIM format was never
|
||||
* intended to be used outside of DSpace, it is admirably suited to
|
||||
* describing the exact state of the descriptive MD stored in the RDBMS.
|
||||
* All crosswalks to standard formats such as MODS and even DC are necessarily
|
||||
* "lossy" and inexact. Since the purpose of an AIP is to preserve and restore
|
||||
* the state of an object exactly, DIM is the preferred format for
|
||||
* recording its descriptive MD.
|
||||
* <p>
|
||||
* In order to allow external applications to make sense of DSpace AIPs for
|
||||
* preservation purposes, we recommend adding a parallel descriptive
|
||||
* metadata section in one of the preferred standard formats such as MODS
|
||||
* as well as the DIM.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.2 $
|
||||
*/
|
||||
public class AIPDIMCrosswalk
|
||||
implements DisseminationCrosswalk, IngestionCrosswalk
|
||||
{
|
||||
/**
|
||||
* Get XML namespaces of the elements this crosswalk may return.
|
||||
* Returns the XML namespaces (as JDOM objects) of the root element.
|
||||
*
|
||||
* @return array of namespaces, which may be empty.
|
||||
*/
|
||||
public Namespace[] getNamespaces()
|
||||
{
|
||||
Namespace result[] = new Namespace[1];
|
||||
result[0] = XSLTCrosswalk.DIM_NS;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the XML Schema location(s) of the target metadata format.
|
||||
* Returns the string value of the <code>xsi:schemaLocation</code>
|
||||
* attribute that should be applied to the generated XML.
|
||||
* <p>
|
||||
* It may return the empty string if no schema is known, but crosswalk
|
||||
* authors are strongly encouraged to implement this call so their output
|
||||
* XML can be validated correctly.
|
||||
* @return SchemaLocation string, including URI namespace, followed by
|
||||
* whitespace and URI of XML schema document, or empty string if unknown.
|
||||
*/
|
||||
public String getSchemaLocation()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate: Can this disseminator crosswalk the given object.
|
||||
* Needed by OAI-PMH server implementation.
|
||||
*
|
||||
* @param dso dspace object, e.g. an <code>Item</code>.
|
||||
* @return true when disseminator is capable of producing metadata.
|
||||
*/
|
||||
public boolean canDisseminate(DSpaceObject dso)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate: Does this disseminator prefer to return a list of Elements,
|
||||
* rather than a single root Element?
|
||||
* <p>
|
||||
* Some metadata formats have an XML schema without a root element,
|
||||
* for example, the Dublin Core and Qualified Dublin Core formats.
|
||||
* This would be <code>true</code> for a crosswalk into QDC, since
|
||||
* it would "prefer" to return a list, since any root element it has
|
||||
* to produce would have to be part of a nonstandard schema. In
|
||||
* most cases your implementation will want to return
|
||||
* <code>false</code>
|
||||
*
|
||||
* @return true when disseminator prefers you call disseminateList().
|
||||
*/
|
||||
public boolean preferList()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute crosswalk, returning List of XML elements.
|
||||
* Returns a <code>List</code> of JDOM <code>Element</code> objects representing
|
||||
* the XML produced by the crosswalk. This is typically called when
|
||||
* a list of fields is desired, e.g. for embedding in a METS document
|
||||
* <code>xmlData</code> field.
|
||||
* <p>
|
||||
* When there are no results, an
|
||||
* empty list is returned, but never <code>null</code>.
|
||||
*
|
||||
* @param dso the DSpace Object whose metadata to export.
|
||||
* @return results of crosswalk as list of XML elements.
|
||||
*
|
||||
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
|
||||
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
|
||||
* @throws IOException I/O failure in services this calls
|
||||
* @throws SQLException Database failure in services this calls
|
||||
* @throws AuthorizeException current user not authorized for this operation.
|
||||
*/
|
||||
public List<Element> disseminateList(DSpaceObject dso)
|
||||
throws CrosswalkException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
Element dim = disseminateElement(dso);
|
||||
return dim.getChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute crosswalk, returning one XML root element as
|
||||
* a JDOM <code>Element</code> object.
|
||||
* This is typically the root element of a document.
|
||||
* <p>
|
||||
*
|
||||
* @param dso the DSpace Object whose metadata to export.
|
||||
* @return root Element of the target metadata, never <code>null</code>
|
||||
*
|
||||
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
|
||||
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
|
||||
* @throws IOException I/O failure in services this calls
|
||||
* @throws SQLException Database failure in services this calls
|
||||
* @throws AuthorizeException current user not authorized for this operation.
|
||||
*/
|
||||
public Element disseminateElement(DSpaceObject dso)
|
||||
throws CrosswalkException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
return XSLTDisseminationCrosswalk.createDIM(dso);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ingest a whole document. Build Document object around root element,
|
||||
* and feed that to the transformation, since it may get handled
|
||||
* differently than a List of metadata elements.
|
||||
*/
|
||||
public void ingest(Context context, DSpaceObject dso, Element root)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
ingest(context, dso, root.getChildren());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fields correspond directly to Item.addMetadata() calls so
|
||||
* they are simply executed.
|
||||
*/
|
||||
public void ingest(Context context, DSpaceObject dso, List<Element> dimList)
|
||||
throws CrosswalkException,
|
||||
IOException, SQLException, AuthorizeException
|
||||
{
|
||||
XSLTIngestionCrosswalk.ingestDIM(context, dso, dimList);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,69 +1,69 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.license.CreativeCommons;
|
||||
|
||||
/**
|
||||
* Export the item's Creative Commons license, RDF form.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class CreativeCommonsRDFStreamDisseminationCrosswalk
|
||||
implements StreamDisseminationCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(CreativeCommonsRDFStreamDisseminationCrosswalk.class);
|
||||
|
||||
public boolean canDisseminate(Context context, DSpaceObject dso)
|
||||
{
|
||||
try
|
||||
{
|
||||
return dso.getType() == Constants.ITEM &&
|
||||
CreativeCommons.getLicenseRdfBitstream((Item)dso) != null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("Failed getting CC license", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
Bitstream cc = CreativeCommons.getLicenseRdfBitstream((Item)dso);
|
||||
if (cc != null)
|
||||
{
|
||||
Utils.copy(cc.retrieve(), out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/xml";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.license.CreativeCommons;
|
||||
|
||||
/**
|
||||
* Export the item's Creative Commons license, RDF form.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class CreativeCommonsRDFStreamDisseminationCrosswalk
|
||||
implements StreamDisseminationCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(CreativeCommonsRDFStreamDisseminationCrosswalk.class);
|
||||
|
||||
public boolean canDisseminate(Context context, DSpaceObject dso)
|
||||
{
|
||||
try
|
||||
{
|
||||
return dso.getType() == Constants.ITEM &&
|
||||
CreativeCommons.getLicenseRdfBitstream((Item)dso) != null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("Failed getting CC license", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
Bitstream cc = CreativeCommons.getLicenseRdfBitstream((Item)dso);
|
||||
if (cc != null)
|
||||
{
|
||||
Utils.copy(cc.retrieve(), out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/xml";
|
||||
}
|
||||
}
|
||||
|
@@ -1,62 +1,62 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.license.CreativeCommons;
|
||||
|
||||
/**
|
||||
* Ingest a Creative Commons license, RDF form.
|
||||
* <p>
|
||||
* Note that this is NOT needed when ingesting a DSpace AIP, since the
|
||||
* CC license is stored as a Bitstream (or two) in a dedicated Bundle;
|
||||
* the normal apparatus of ingestig the AIP will restore that Bitstream
|
||||
* with its proper name and thus the presence of the CC license.
|
||||
* <p>
|
||||
* This crosswalk should only be used when ingesting other kinds of SIPs.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class CreativeCommonsRDFStreamIngestionCrosswalk
|
||||
implements StreamIngestionCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(CreativeCommonsRDFStreamIngestionCrosswalk.class);
|
||||
|
||||
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
// If package includes a Creative Commons license, add that:
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Reading a Creative Commons license, MIMEtype=" + MIMEType);
|
||||
}
|
||||
|
||||
CreativeCommons.setLicense(context, (Item)dso, in, MIMEType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/rdf";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.license.CreativeCommons;
|
||||
|
||||
/**
|
||||
* Ingest a Creative Commons license, RDF form.
|
||||
* <p>
|
||||
* Note that this is NOT needed when ingesting a DSpace AIP, since the
|
||||
* CC license is stored as a Bitstream (or two) in a dedicated Bundle;
|
||||
* the normal apparatus of ingestig the AIP will restore that Bitstream
|
||||
* with its proper name and thus the presence of the CC license.
|
||||
* <p>
|
||||
* This crosswalk should only be used when ingesting other kinds of SIPs.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class CreativeCommonsRDFStreamIngestionCrosswalk
|
||||
implements StreamIngestionCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(CreativeCommonsRDFStreamIngestionCrosswalk.class);
|
||||
|
||||
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
// If package includes a Creative Commons license, add that:
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Reading a Creative Commons license, MIMEtype=" + MIMEType);
|
||||
}
|
||||
|
||||
CreativeCommons.setLicense(context, (Item)dso, in, MIMEType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/rdf";
|
||||
}
|
||||
}
|
||||
|
@@ -1,69 +1,69 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.license.CreativeCommons;
|
||||
|
||||
/**
|
||||
* Export the object's Creative Commons license, text form.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class CreativeCommonsTextStreamDisseminationCrosswalk
|
||||
implements StreamDisseminationCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(CreativeCommonsTextStreamDisseminationCrosswalk.class);
|
||||
|
||||
public boolean canDisseminate(Context context, DSpaceObject dso)
|
||||
{
|
||||
try
|
||||
{
|
||||
return dso.getType() == Constants.ITEM &&
|
||||
CreativeCommons.getLicenseTextBitstream((Item)dso) != null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("Failed getting CC license", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
Bitstream cc = CreativeCommons.getLicenseTextBitstream((Item)dso);
|
||||
if (cc != null)
|
||||
{
|
||||
Utils.copy(cc.retrieve(), out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.license.CreativeCommons;
|
||||
|
||||
/**
|
||||
* Export the object's Creative Commons license, text form.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class CreativeCommonsTextStreamDisseminationCrosswalk
|
||||
implements StreamDisseminationCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(CreativeCommonsTextStreamDisseminationCrosswalk.class);
|
||||
|
||||
public boolean canDisseminate(Context context, DSpaceObject dso)
|
||||
{
|
||||
try
|
||||
{
|
||||
return dso.getType() == Constants.ITEM &&
|
||||
CreativeCommons.getLicenseTextBitstream((Item)dso) != null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("Failed getting CC license", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
Bitstream cc = CreativeCommons.getLicenseTextBitstream((Item)dso);
|
||||
if (cc != null)
|
||||
{
|
||||
Utils.copy(cc.retrieve(), out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
|
@@ -1,21 +1,21 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
public interface IConverter
|
||||
{
|
||||
/**
|
||||
* Get an alternative format for the input string. Useful examples are
|
||||
* conversion from a metadata language value in ISO-639-3 to ISO-639-1, etc.
|
||||
*
|
||||
* @param value
|
||||
* the input string to convert
|
||||
* @return the converted string returned by the "conversion algorithm"
|
||||
*/
|
||||
public String makeConversion(String value);
|
||||
}
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
public interface IConverter
|
||||
{
|
||||
/**
|
||||
* Get an alternative format for the input string. Useful examples are
|
||||
* conversion from a metadata language value in ISO-639-3 to ISO-639-1, etc.
|
||||
*
|
||||
* @param value
|
||||
* the input string to convert
|
||||
* @return the converted string returned by the "conversion algorithm"
|
||||
*/
|
||||
public String makeConversion(String value);
|
||||
}
|
||||
|
@@ -1,70 +1,70 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.packager.PackageUtils;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
|
||||
/**
|
||||
* Export the object's DSpace deposit license.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class LicenseStreamDisseminationCrosswalk
|
||||
implements StreamDisseminationCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(LicenseStreamDisseminationCrosswalk.class);
|
||||
|
||||
public boolean canDisseminate(Context context, DSpaceObject dso)
|
||||
{
|
||||
try
|
||||
{
|
||||
return dso.getType() == Constants.ITEM &&
|
||||
PackageUtils.findDepositLicense(context, (Item)dso) != null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("Failed getting Deposit license", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
Bitstream licenseBs = PackageUtils.findDepositLicense(context, (Item)dso);
|
||||
|
||||
if (licenseBs != null)
|
||||
{
|
||||
Utils.copy(licenseBs.retrieve(), out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.packager.PackageUtils;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
|
||||
/**
|
||||
* Export the object's DSpace deposit license.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class LicenseStreamDisseminationCrosswalk
|
||||
implements StreamDisseminationCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(LicenseStreamDisseminationCrosswalk.class);
|
||||
|
||||
public boolean canDisseminate(Context context, DSpaceObject dso)
|
||||
{
|
||||
try
|
||||
{
|
||||
return dso.getType() == Constants.ITEM &&
|
||||
PackageUtils.findDepositLicense(context, (Item)dso) != null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("Failed getting Deposit license", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void disseminate(Context context, DSpaceObject dso, OutputStream out)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
Bitstream licenseBs = PackageUtils.findDepositLicense(context, (Item)dso);
|
||||
|
||||
if (licenseBs != null)
|
||||
{
|
||||
Utils.copy(licenseBs.retrieve(), out);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
|
@@ -1,66 +1,66 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.packager.PackageUtils;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
|
||||
/**
|
||||
* Accept a DSpace deposit license.
|
||||
* <p>
|
||||
* Note that this is NOT needed when ingesting a DSpace AIP, since the
|
||||
* deposit license is stored as a Bitstream (or two) in a dedicated Bundle;
|
||||
* the normal apparatus of ingestig the AIP will restore that Bitstream
|
||||
* with its proper name and thus the presence of the deposit license.
|
||||
* <p>
|
||||
* This crosswalk should only be used when ingesting other kinds of SIPs.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class LicenseStreamIngestionCrosswalk
|
||||
implements StreamIngestionCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(LicenseStreamIngestionCrosswalk.class);
|
||||
|
||||
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
// If package includes a Creative Commons license, add that:
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Reading a DSpace Deposit license, MIMEtype=" + MIMEType);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
Utils.copy(in, baos);
|
||||
PackageUtils.addDepositLicense(context, baos.toString(),
|
||||
(Item)dso, null);
|
||||
}
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.packager.PackageUtils;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Utils;
|
||||
|
||||
/**
|
||||
* Accept a DSpace deposit license.
|
||||
* <p>
|
||||
* Note that this is NOT needed when ingesting a DSpace AIP, since the
|
||||
* deposit license is stored as a Bitstream (or two) in a dedicated Bundle;
|
||||
* the normal apparatus of ingestig the AIP will restore that Bitstream
|
||||
* with its proper name and thus the presence of the deposit license.
|
||||
* <p>
|
||||
* This crosswalk should only be used when ingesting other kinds of SIPs.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class LicenseStreamIngestionCrosswalk
|
||||
implements StreamIngestionCrosswalk
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(LicenseStreamIngestionCrosswalk.class);
|
||||
|
||||
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
// If package includes a Creative Commons license, add that:
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug("Reading a DSpace Deposit license, MIMEtype=" + MIMEType);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
Utils.copy(in, baos);
|
||||
PackageUtils.addDepositLicense(context, baos.toString(),
|
||||
(Item)dso, null);
|
||||
}
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,43 +1,43 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
/**
|
||||
* A crosswalk to ignore and dispose of the ingested material.
|
||||
* <p>
|
||||
* Specify this crosswalk in the mapping of e.g. METS metadata field
|
||||
* types to crosswalks when you wish to ignore a redundant or unknown
|
||||
* type of metadata. For example, when ingesting a DSpace AIP with an
|
||||
* AIP ingester, it is best to ignore the rightsMD fields since they
|
||||
* are already going to be ingested as member bitstreams anyway.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class NullStreamIngestionCrosswalk
|
||||
implements StreamIngestionCrosswalk
|
||||
{
|
||||
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
/**
|
||||
* A crosswalk to ignore and dispose of the ingested material.
|
||||
* <p>
|
||||
* Specify this crosswalk in the mapping of e.g. METS metadata field
|
||||
* types to crosswalks when you wish to ignore a redundant or unknown
|
||||
* type of metadata. For example, when ingesting a DSpace AIP with an
|
||||
* AIP ingester, it is best to ignore the rightsMD fields since they
|
||||
* are already going to be ingested as member bitstreams anyway.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class NullStreamIngestionCrosswalk
|
||||
implements StreamIngestionCrosswalk
|
||||
{
|
||||
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
|
||||
public String getMIMEType()
|
||||
{
|
||||
return "text/plain";
|
||||
}
|
||||
}
|
||||
|
@@ -1,342 +1,342 @@
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.packager.PackageDisseminator;
|
||||
import org.dspace.content.packager.PackageException;
|
||||
import org.dspace.content.packager.PackageIngester;
|
||||
import org.dspace.content.packager.PackageParameters;
|
||||
import org.dspace.content.packager.RoleDisseminator;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.PluginManager;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.Namespace;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
|
||||
/**
|
||||
* Role Crosswalk
|
||||
* <p>
|
||||
* Translate between DSpace Group & EPeople definitions and a DSpace-specific
|
||||
* XML export format (generated by the RoleDisseminator). This is primarily
|
||||
* used for AIPs, but may be used by other Packagers as necessary.
|
||||
* <p>
|
||||
* This crosswalk allows you to export DSpace Groups & EPeople to this XML
|
||||
* structured format. It also allows you to import an XML file of this format
|
||||
* in order to restore DSpace Groups and EPeople defined within it.
|
||||
* <p>
|
||||
* This is just wrappers; the real work is done in RoleDisseminator and
|
||||
* RoleIngester.
|
||||
*
|
||||
* @author mwood
|
||||
* @author Tim Donohue
|
||||
* @see org.dspace.content.packager.RoleDisseminator
|
||||
* @see org.dspace.content.packager.RoleIngester
|
||||
* @see AbstractPackagerWrappingCrosswalk
|
||||
* @see IngestionCrosswalk
|
||||
* @see DisseminationCrosswalk
|
||||
*/
|
||||
public class RoleCrosswalk
|
||||
extends AbstractPackagerWrappingCrosswalk
|
||||
implements IngestionCrosswalk, DisseminationCrosswalk
|
||||
{
|
||||
// Plugin Name of DSPACE-ROLES packager to use for ingest/dissemination
|
||||
// (Whatever plugin is defined with this name in 'dspace.cfg' will be used by this Crosswalk)
|
||||
private static final String ROLE_PACKAGER_PLUGIN = "DSPACE-ROLES";
|
||||
|
||||
// ---- Dissemination Methods -----------
|
||||
|
||||
/**
|
||||
* Get XML namespaces of the elements this crosswalk may return.
|
||||
* Returns the XML namespaces (as JDOM objects) of the root element.
|
||||
*
|
||||
* @return array of namespaces, which may be empty.
|
||||
*/
|
||||
@Override
|
||||
public Namespace[] getNamespaces()
|
||||
{
|
||||
Namespace result[] = new Namespace[1];
|
||||
result[0] = RoleDisseminator.DSROLES_NS;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the XML Schema location(s) of the target metadata format.
|
||||
* Returns the string value of the <code>xsi:schemaLocation</code>
|
||||
* attribute that should be applied to the generated XML.
|
||||
* <p>
|
||||
* It may return the empty string if no schema is known, but crosswalk
|
||||
* authors are strongly encouraged to implement this call so their output
|
||||
* XML can be validated correctly.
|
||||
* @return SchemaLocation string, including URI namespace, followed by
|
||||
* whitespace and URI of XML schema document, or empty string if unknown.
|
||||
*/
|
||||
@Override
|
||||
public String getSchemaLocation()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate: Can this disseminator crosswalk the given object.
|
||||
*
|
||||
* @param dso dspace object, e.g. an <code>Item</code>.
|
||||
* @return true when disseminator is capable of producing metadata.
|
||||
*/
|
||||
@Override
|
||||
public boolean canDisseminate(DSpaceObject dso)
|
||||
{
|
||||
//We can only disseminate SITE, COMMUNITY or COLLECTION objects,
|
||||
//as Groups are only associated with those objects.
|
||||
return (dso.getType() == Constants.SITE ||
|
||||
dso.getType() == Constants.COMMUNITY ||
|
||||
dso.getType() == Constants.COLLECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate: Does this disseminator prefer to return a list of Elements,
|
||||
* rather than a single root Element?
|
||||
*
|
||||
* @return true when disseminator prefers you call disseminateList().
|
||||
*/
|
||||
@Override
|
||||
public boolean preferList()
|
||||
{
|
||||
//We prefer disseminators call 'disseminateElement()' instead of 'disseminateList()'
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute crosswalk, returning List of XML elements.
|
||||
* Returns a <code>List</code> of JDOM <code>Element</code> objects representing
|
||||
* the XML produced by the crosswalk. This is typically called when
|
||||
* a list of fields is desired, e.g. for embedding in a METS document
|
||||
* <code>xmlData</code> field.
|
||||
* <p>
|
||||
* When there are no results, an
|
||||
* empty list is returned, but never <code>null</code>.
|
||||
*
|
||||
* @param dso the DSpace Object whose metadata to export.
|
||||
* @return results of crosswalk as list of XML elements.
|
||||
*
|
||||
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
|
||||
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
|
||||
* @throws IOException I/O failure in services this calls
|
||||
* @throws SQLException Database failure in services this calls
|
||||
* @throws AuthorizeException current user not authorized for this operation.
|
||||
*/
|
||||
@Override
|
||||
public List<Element> disseminateList(DSpaceObject dso)
|
||||
throws CrosswalkException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
Element dim = disseminateElement(dso);
|
||||
return dim.getChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute crosswalk, returning one XML root element as
|
||||
* a JDOM <code>Element</code> object.
|
||||
* This is typically the root element of a document.
|
||||
* <p>
|
||||
*
|
||||
* @param dso the DSpace Object whose metadata to export.
|
||||
* @return root Element of the target metadata, never <code>null</code>
|
||||
*
|
||||
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
|
||||
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
|
||||
* @throws IOException I/O failure in services this calls
|
||||
* @throws SQLException Database failure in services this calls
|
||||
* @throws AuthorizeException current user not authorized for this operation.
|
||||
*/
|
||||
@Override
|
||||
public Element disseminateElement(DSpaceObject dso)
|
||||
throws CrosswalkException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
try
|
||||
{
|
||||
PackageDisseminator dip = (PackageDisseminator)
|
||||
PluginManager.getNamedPlugin(PackageDisseminator.class, ROLE_PACKAGER_PLUGIN);
|
||||
if (dip == null)
|
||||
{
|
||||
throw new CrosswalkInternalException("Cannot find a PackageDisseminator plugin named " + ROLE_PACKAGER_PLUGIN);
|
||||
}
|
||||
|
||||
// Create a temporary file to disseminate into
|
||||
String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir");
|
||||
File tempFile = File.createTempFile("RoleCrosswalkDisseminate" + dso.hashCode(), null, new File(tempDirectory));
|
||||
tempFile.deleteOnExit();
|
||||
|
||||
// Initialize our packaging parameters
|
||||
PackageParameters pparams;
|
||||
if(this.getPackagingParameters()!=null)
|
||||
{
|
||||
pparams = this.getPackagingParameters();
|
||||
}
|
||||
else
|
||||
{
|
||||
pparams = new PackageParameters();
|
||||
}
|
||||
|
||||
//actually disseminate to our temp file.
|
||||
Context context = new Context();
|
||||
dip.disseminate(context, dso, pparams, tempFile);
|
||||
|
||||
// if we ended up with a Zero-length output file,
|
||||
// this means dissemination was successful but had no results
|
||||
if(tempFile.exists() && tempFile.length()==0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//Try to parse our XML results (which were disseminated by the Packager)
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
Document xmlDocument = builder.build(tempFile);
|
||||
//If XML parsed successfully, return root element of doc
|
||||
if(xmlDocument!=null && xmlDocument.hasRootElement())
|
||||
{
|
||||
return xmlDocument.getRootElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (JDOMException je)
|
||||
{
|
||||
throw new MetadataValidationException("Error parsing Roles XML (see wrapped error message for more details) ",je);
|
||||
}
|
||||
}
|
||||
catch (PackageException pe)
|
||||
{
|
||||
throw new CrosswalkInternalException("Failed to export Roles via packager (see wrapped error message for more details) ",pe);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Ingestion Methods -----------
|
||||
|
||||
|
||||
/**
|
||||
* Ingest a List of XML elements
|
||||
*
|
||||
* @param context
|
||||
* @param dso
|
||||
* @param metadata
|
||||
* @throws CrosswalkException
|
||||
* @throws IOException
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
@Override
|
||||
public void ingest(Context context, DSpaceObject dso, List<Element> metadata)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if(!metadata.isEmpty())
|
||||
{
|
||||
ingest(context, dso, ((Element) metadata.get(0)).getParentElement());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ingest a whole XML document, starting at specified root.
|
||||
* <P>
|
||||
* This essentially just wraps a call to the configured Role PackageIngester.
|
||||
*
|
||||
* @param context
|
||||
* @param dso
|
||||
* @param root
|
||||
* @throws CrosswalkException
|
||||
* @throws IOException
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
@Override
|
||||
public void ingest(Context context, DSpaceObject dso, Element root)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if (dso.getType() != Constants.SITE &&
|
||||
dso.getType() != Constants.COMMUNITY &&
|
||||
dso.getType() != Constants.COLLECTION)
|
||||
{
|
||||
throw new CrosswalkObjectNotSupported("Role crosswalk only valid for Site, Community or Collection");
|
||||
}
|
||||
|
||||
//locate our "DSPACE-ROLES" PackageIngester plugin
|
||||
PackageIngester sip = (PackageIngester)
|
||||
PluginManager.getNamedPlugin(PackageIngester.class, ROLE_PACKAGER_PLUGIN);
|
||||
if (sip == null)
|
||||
{
|
||||
throw new CrosswalkInternalException("Cannot find a PackageIngester plugin named " + ROLE_PACKAGER_PLUGIN);
|
||||
}
|
||||
|
||||
// Initialize our packaging parameters
|
||||
PackageParameters pparams;
|
||||
if(this.getPackagingParameters()!=null)
|
||||
{
|
||||
pparams = this.getPackagingParameters();
|
||||
}
|
||||
else
|
||||
{
|
||||
pparams = new PackageParameters();
|
||||
}
|
||||
|
||||
// Initialize our license info
|
||||
String license = null;
|
||||
if(this.getIngestionLicense()!=null)
|
||||
{
|
||||
license = this.getIngestionLicense();
|
||||
}
|
||||
|
||||
// Create a temporary file to ingest from
|
||||
String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir");
|
||||
File tempFile = File.createTempFile("RoleCrosswalkIngest" + dso.hashCode(), null, new File(tempDirectory));
|
||||
tempFile.deleteOnExit();
|
||||
FileOutputStream fileOutStream = null;
|
||||
try
|
||||
{
|
||||
fileOutStream = new FileOutputStream(tempFile);
|
||||
XMLOutputter writer = new XMLOutputter();
|
||||
writer.output(root, fileOutStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fileOutStream != null)
|
||||
{
|
||||
fileOutStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
//Actually call the ingester
|
||||
try
|
||||
{
|
||||
sip.ingest(context, dso, tempFile, pparams, license);
|
||||
}
|
||||
catch (PackageException e)
|
||||
{
|
||||
throw new CrosswalkInternalException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.content.crosswalk;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.packager.PackageDisseminator;
|
||||
import org.dspace.content.packager.PackageException;
|
||||
import org.dspace.content.packager.PackageIngester;
|
||||
import org.dspace.content.packager.PackageParameters;
|
||||
import org.dspace.content.packager.RoleDisseminator;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.PluginManager;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.Namespace;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
|
||||
/**
|
||||
* Role Crosswalk
|
||||
* <p>
|
||||
* Translate between DSpace Group & EPeople definitions and a DSpace-specific
|
||||
* XML export format (generated by the RoleDisseminator). This is primarily
|
||||
* used for AIPs, but may be used by other Packagers as necessary.
|
||||
* <p>
|
||||
* This crosswalk allows you to export DSpace Groups & EPeople to this XML
|
||||
* structured format. It also allows you to import an XML file of this format
|
||||
* in order to restore DSpace Groups and EPeople defined within it.
|
||||
* <p>
|
||||
* This is just wrappers; the real work is done in RoleDisseminator and
|
||||
* RoleIngester.
|
||||
*
|
||||
* @author mwood
|
||||
* @author Tim Donohue
|
||||
* @see org.dspace.content.packager.RoleDisseminator
|
||||
* @see org.dspace.content.packager.RoleIngester
|
||||
* @see AbstractPackagerWrappingCrosswalk
|
||||
* @see IngestionCrosswalk
|
||||
* @see DisseminationCrosswalk
|
||||
*/
|
||||
public class RoleCrosswalk
|
||||
extends AbstractPackagerWrappingCrosswalk
|
||||
implements IngestionCrosswalk, DisseminationCrosswalk
|
||||
{
|
||||
// Plugin Name of DSPACE-ROLES packager to use for ingest/dissemination
|
||||
// (Whatever plugin is defined with this name in 'dspace.cfg' will be used by this Crosswalk)
|
||||
private static final String ROLE_PACKAGER_PLUGIN = "DSPACE-ROLES";
|
||||
|
||||
// ---- Dissemination Methods -----------
|
||||
|
||||
/**
|
||||
* Get XML namespaces of the elements this crosswalk may return.
|
||||
* Returns the XML namespaces (as JDOM objects) of the root element.
|
||||
*
|
||||
* @return array of namespaces, which may be empty.
|
||||
*/
|
||||
@Override
|
||||
public Namespace[] getNamespaces()
|
||||
{
|
||||
Namespace result[] = new Namespace[1];
|
||||
result[0] = RoleDisseminator.DSROLES_NS;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the XML Schema location(s) of the target metadata format.
|
||||
* Returns the string value of the <code>xsi:schemaLocation</code>
|
||||
* attribute that should be applied to the generated XML.
|
||||
* <p>
|
||||
* It may return the empty string if no schema is known, but crosswalk
|
||||
* authors are strongly encouraged to implement this call so their output
|
||||
* XML can be validated correctly.
|
||||
* @return SchemaLocation string, including URI namespace, followed by
|
||||
* whitespace and URI of XML schema document, or empty string if unknown.
|
||||
*/
|
||||
@Override
|
||||
public String getSchemaLocation()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate: Can this disseminator crosswalk the given object.
|
||||
*
|
||||
* @param dso dspace object, e.g. an <code>Item</code>.
|
||||
* @return true when disseminator is capable of producing metadata.
|
||||
*/
|
||||
@Override
|
||||
public boolean canDisseminate(DSpaceObject dso)
|
||||
{
|
||||
//We can only disseminate SITE, COMMUNITY or COLLECTION objects,
|
||||
//as Groups are only associated with those objects.
|
||||
return (dso.getType() == Constants.SITE ||
|
||||
dso.getType() == Constants.COMMUNITY ||
|
||||
dso.getType() == Constants.COLLECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate: Does this disseminator prefer to return a list of Elements,
|
||||
* rather than a single root Element?
|
||||
*
|
||||
* @return true when disseminator prefers you call disseminateList().
|
||||
*/
|
||||
@Override
|
||||
public boolean preferList()
|
||||
{
|
||||
//We prefer disseminators call 'disseminateElement()' instead of 'disseminateList()'
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute crosswalk, returning List of XML elements.
|
||||
* Returns a <code>List</code> of JDOM <code>Element</code> objects representing
|
||||
* the XML produced by the crosswalk. This is typically called when
|
||||
* a list of fields is desired, e.g. for embedding in a METS document
|
||||
* <code>xmlData</code> field.
|
||||
* <p>
|
||||
* When there are no results, an
|
||||
* empty list is returned, but never <code>null</code>.
|
||||
*
|
||||
* @param dso the DSpace Object whose metadata to export.
|
||||
* @return results of crosswalk as list of XML elements.
|
||||
*
|
||||
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
|
||||
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
|
||||
* @throws IOException I/O failure in services this calls
|
||||
* @throws SQLException Database failure in services this calls
|
||||
* @throws AuthorizeException current user not authorized for this operation.
|
||||
*/
|
||||
@Override
|
||||
public List<Element> disseminateList(DSpaceObject dso)
|
||||
throws CrosswalkException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
Element dim = disseminateElement(dso);
|
||||
return dim.getChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute crosswalk, returning one XML root element as
|
||||
* a JDOM <code>Element</code> object.
|
||||
* This is typically the root element of a document.
|
||||
* <p>
|
||||
*
|
||||
* @param dso the DSpace Object whose metadata to export.
|
||||
* @return root Element of the target metadata, never <code>null</code>
|
||||
*
|
||||
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
|
||||
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
|
||||
* @throws IOException I/O failure in services this calls
|
||||
* @throws SQLException Database failure in services this calls
|
||||
* @throws AuthorizeException current user not authorized for this operation.
|
||||
*/
|
||||
@Override
|
||||
public Element disseminateElement(DSpaceObject dso)
|
||||
throws CrosswalkException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
try
|
||||
{
|
||||
PackageDisseminator dip = (PackageDisseminator)
|
||||
PluginManager.getNamedPlugin(PackageDisseminator.class, ROLE_PACKAGER_PLUGIN);
|
||||
if (dip == null)
|
||||
{
|
||||
throw new CrosswalkInternalException("Cannot find a PackageDisseminator plugin named " + ROLE_PACKAGER_PLUGIN);
|
||||
}
|
||||
|
||||
// Create a temporary file to disseminate into
|
||||
String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir");
|
||||
File tempFile = File.createTempFile("RoleCrosswalkDisseminate" + dso.hashCode(), null, new File(tempDirectory));
|
||||
tempFile.deleteOnExit();
|
||||
|
||||
// Initialize our packaging parameters
|
||||
PackageParameters pparams;
|
||||
if(this.getPackagingParameters()!=null)
|
||||
{
|
||||
pparams = this.getPackagingParameters();
|
||||
}
|
||||
else
|
||||
{
|
||||
pparams = new PackageParameters();
|
||||
}
|
||||
|
||||
//actually disseminate to our temp file.
|
||||
Context context = new Context();
|
||||
dip.disseminate(context, dso, pparams, tempFile);
|
||||
|
||||
// if we ended up with a Zero-length output file,
|
||||
// this means dissemination was successful but had no results
|
||||
if(tempFile.exists() && tempFile.length()==0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//Try to parse our XML results (which were disseminated by the Packager)
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
Document xmlDocument = builder.build(tempFile);
|
||||
//If XML parsed successfully, return root element of doc
|
||||
if(xmlDocument!=null && xmlDocument.hasRootElement())
|
||||
{
|
||||
return xmlDocument.getRootElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (JDOMException je)
|
||||
{
|
||||
throw new MetadataValidationException("Error parsing Roles XML (see wrapped error message for more details) ",je);
|
||||
}
|
||||
}
|
||||
catch (PackageException pe)
|
||||
{
|
||||
throw new CrosswalkInternalException("Failed to export Roles via packager (see wrapped error message for more details) ",pe);
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Ingestion Methods -----------
|
||||
|
||||
|
||||
/**
|
||||
* Ingest a List of XML elements
|
||||
*
|
||||
* @param context
|
||||
* @param dso
|
||||
* @param metadata
|
||||
* @throws CrosswalkException
|
||||
* @throws IOException
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
@Override
|
||||
public void ingest(Context context, DSpaceObject dso, List<Element> metadata)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if(!metadata.isEmpty())
|
||||
{
|
||||
ingest(context, dso, ((Element) metadata.get(0)).getParentElement());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ingest a whole XML document, starting at specified root.
|
||||
* <P>
|
||||
* This essentially just wraps a call to the configured Role PackageIngester.
|
||||
*
|
||||
* @param context
|
||||
* @param dso
|
||||
* @param root
|
||||
* @throws CrosswalkException
|
||||
* @throws IOException
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
@Override
|
||||
public void ingest(Context context, DSpaceObject dso, Element root)
|
||||
throws CrosswalkException, IOException, SQLException, AuthorizeException
|
||||
{
|
||||
if (dso.getType() != Constants.SITE &&
|
||||
dso.getType() != Constants.COMMUNITY &&
|
||||
dso.getType() != Constants.COLLECTION)
|
||||
{
|
||||
throw new CrosswalkObjectNotSupported("Role crosswalk only valid for Site, Community or Collection");
|
||||
}
|
||||
|
||||
//locate our "DSPACE-ROLES" PackageIngester plugin
|
||||
PackageIngester sip = (PackageIngester)
|
||||
PluginManager.getNamedPlugin(PackageIngester.class, ROLE_PACKAGER_PLUGIN);
|
||||
if (sip == null)
|
||||
{
|
||||
throw new CrosswalkInternalException("Cannot find a PackageIngester plugin named " + ROLE_PACKAGER_PLUGIN);
|
||||
}
|
||||
|
||||
// Initialize our packaging parameters
|
||||
PackageParameters pparams;
|
||||
if(this.getPackagingParameters()!=null)
|
||||
{
|
||||
pparams = this.getPackagingParameters();
|
||||
}
|
||||
else
|
||||
{
|
||||
pparams = new PackageParameters();
|
||||
}
|
||||
|
||||
// Initialize our license info
|
||||
String license = null;
|
||||
if(this.getIngestionLicense()!=null)
|
||||
{
|
||||
license = this.getIngestionLicense();
|
||||
}
|
||||
|
||||
// Create a temporary file to ingest from
|
||||
String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir");
|
||||
File tempFile = File.createTempFile("RoleCrosswalkIngest" + dso.hashCode(), null, new File(tempDirectory));
|
||||
tempFile.deleteOnExit();
|
||||
FileOutputStream fileOutStream = null;
|
||||
try
|
||||
{
|
||||
fileOutStream = new FileOutputStream(tempFile);
|
||||
XMLOutputter writer = new XMLOutputter();
|
||||
writer.output(root, fileOutStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fileOutStream != null)
|
||||
{
|
||||
fileOutStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
//Actually call the ingester
|
||||
try
|
||||
{
|
||||
sip.ingest(context, dso, tempFile, pparams, license);
|
||||
}
|
||||
catch (PackageException e)
|
||||
{
|
||||
throw new CrosswalkInternalException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,51 +1,51 @@
|
||||
/**
|
||||
* 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.content.license;
|
||||
|
||||
import java.util.Formattable;
|
||||
import java.util.Formatter;
|
||||
|
||||
import org.dspace.core.PluginManager;
|
||||
|
||||
/**
|
||||
* Wrapper class to make formattable any argument used in the license template.
|
||||
* The formatter behavior is delegated to a specific class on "type" basis
|
||||
* using the PluginManager
|
||||
*
|
||||
* @see Formattable
|
||||
* @see LicenseArgumentFormatter
|
||||
* @author bollini
|
||||
*
|
||||
*/
|
||||
public class FormattableArgument implements Formattable
|
||||
{
|
||||
private String type;
|
||||
|
||||
private Object object;
|
||||
|
||||
public FormattableArgument(String type, Object object)
|
||||
{
|
||||
this.type = type;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public void formatTo(Formatter formatter, int flags, int width,
|
||||
int precision)
|
||||
{
|
||||
LicenseArgumentFormatter laf = (LicenseArgumentFormatter) PluginManager
|
||||
.getNamedPlugin(LicenseArgumentFormatter.class, type);
|
||||
if (laf != null)
|
||||
{
|
||||
laf.formatTo(formatter, flags, width, object, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter.format(object.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.license;
|
||||
|
||||
import java.util.Formattable;
|
||||
import java.util.Formatter;
|
||||
|
||||
import org.dspace.core.PluginManager;
|
||||
|
||||
/**
|
||||
* Wrapper class to make formattable any argument used in the license template.
|
||||
* The formatter behavior is delegated to a specific class on "type" basis
|
||||
* using the PluginManager
|
||||
*
|
||||
* @see Formattable
|
||||
* @see LicenseArgumentFormatter
|
||||
* @author bollini
|
||||
*
|
||||
*/
|
||||
public class FormattableArgument implements Formattable
|
||||
{
|
||||
private String type;
|
||||
|
||||
private Object object;
|
||||
|
||||
public FormattableArgument(String type, Object object)
|
||||
{
|
||||
this.type = type;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public void formatTo(Formatter formatter, int flags, int width,
|
||||
int precision)
|
||||
{
|
||||
LicenseArgumentFormatter laf = (LicenseArgumentFormatter) PluginManager
|
||||
.getNamedPlugin(LicenseArgumentFormatter.class, type);
|
||||
if (laf != null)
|
||||
{
|
||||
laf.formatTo(formatter, flags, width, object, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter.format(object.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,37 +1,37 @@
|
||||
/**
|
||||
* 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.content.license;
|
||||
|
||||
import java.util.Formatter;
|
||||
|
||||
public interface LicenseArgumentFormatter
|
||||
{
|
||||
|
||||
/**
|
||||
* Format the object following the <code>java.util.Formatter</code> rules.
|
||||
* The object type is expected to be know to the implementer can is free to
|
||||
* assume safe to cast as appropriate. If a <code>null</code> object is
|
||||
* supplied is expected that the implementer will work as if a "sample data"
|
||||
* was requested.
|
||||
*
|
||||
* @see Formatter
|
||||
* @param formatter
|
||||
* the current formatter that need to process the object
|
||||
* @param flags
|
||||
* the flags option for the formatter
|
||||
* @param width
|
||||
* the width option for the formatter
|
||||
* @param object
|
||||
* the object to be formatted
|
||||
* @param type
|
||||
* the type of the object (this is an alias not the class name! -
|
||||
* i.e. item, collection, eperson, etc.)
|
||||
*/
|
||||
void formatTo(Formatter formatter, int flags, int width, Object object,
|
||||
String type);
|
||||
}
|
||||
/**
|
||||
* 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.content.license;
|
||||
|
||||
import java.util.Formatter;
|
||||
|
||||
public interface LicenseArgumentFormatter
|
||||
{
|
||||
|
||||
/**
|
||||
* Format the object following the <code>java.util.Formatter</code> rules.
|
||||
* The object type is expected to be know to the implementer can is free to
|
||||
* assume safe to cast as appropriate. If a <code>null</code> object is
|
||||
* supplied is expected that the implementer will work as if a "sample data"
|
||||
* was requested.
|
||||
*
|
||||
* @see Formatter
|
||||
* @param formatter
|
||||
* the current formatter that need to process the object
|
||||
* @param flags
|
||||
* the flags option for the formatter
|
||||
* @param width
|
||||
* the width option for the formatter
|
||||
* @param object
|
||||
* the object to be formatted
|
||||
* @param type
|
||||
* the type of the object (this is an alias not the class name! -
|
||||
* i.e. item, collection, eperson, etc.)
|
||||
*/
|
||||
void formatTo(Formatter formatter, int flags, int width, Object object,
|
||||
String type);
|
||||
}
|
||||
|
@@ -1,45 +1,45 @@
|
||||
/**
|
||||
* 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.content.license;
|
||||
|
||||
import java.util.Formatter;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
|
||||
/**
|
||||
* This is a simple implementation of the LicenseArgumentFormatter for a
|
||||
* DSpaceObject. The formatter options width/precision are not take in care.
|
||||
*
|
||||
* @author bollini
|
||||
*
|
||||
*/
|
||||
public class SimpleDSpaceObjectLicenseFormatter implements
|
||||
LicenseArgumentFormatter
|
||||
{
|
||||
public void formatTo(Formatter formatter, int flags, int width,
|
||||
Object object, String type)
|
||||
{
|
||||
if (object == null)
|
||||
{
|
||||
formatter.format("sample "+type);
|
||||
}
|
||||
else
|
||||
{
|
||||
DSpaceObject dso = (DSpaceObject) object;
|
||||
String name = dso.getName();
|
||||
if (name != null)
|
||||
{
|
||||
formatter.format(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter.format("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.license;
|
||||
|
||||
import java.util.Formatter;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
|
||||
/**
|
||||
* This is a simple implementation of the LicenseArgumentFormatter for a
|
||||
* DSpaceObject. The formatter options width/precision are not take in care.
|
||||
*
|
||||
* @author bollini
|
||||
*
|
||||
*/
|
||||
public class SimpleDSpaceObjectLicenseFormatter implements
|
||||
LicenseArgumentFormatter
|
||||
{
|
||||
public void formatTo(Formatter formatter, int flags, int width,
|
||||
Object object, String type)
|
||||
{
|
||||
if (object == null)
|
||||
{
|
||||
formatter.format("sample "+type);
|
||||
}
|
||||
else
|
||||
{
|
||||
DSpaceObject dso = (DSpaceObject) object;
|
||||
String name = dso.getName();
|
||||
if (name != null)
|
||||
{
|
||||
formatter.format(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter.format("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@ import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.FormatIdentifier;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.WorkspaceItem;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
import org.dspace.content.crosswalk.MetadataValidationException;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
@@ -36,7 +37,6 @@ import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.handle.HandleManager;
|
||||
import org.dspace.workflow.WorkflowItem;
|
||||
import org.jdom.Element;
|
||||
|
||||
/**
|
||||
@@ -459,24 +459,34 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester
|
||||
manifest.crosswalkObjectOtherAdminMD(context, params, dso, callback);
|
||||
|
||||
// -- Step 4 --
|
||||
// Run our Descriptive metadata (dublin core, etc) crosswalks!
|
||||
crosswalkObjectDmd(context, dso, manifest, callback, manifest
|
||||
.getItemDmds(), params);
|
||||
|
||||
// For Items, also sanity-check the metadata for minimum requirements.
|
||||
if (type == Constants.ITEM)
|
||||
{
|
||||
PackageUtils.checkItemMetadata((Item) dso);
|
||||
}
|
||||
|
||||
// -- Step 5 --
|
||||
// Add all content files as bitstreams on new DSpace Object
|
||||
if (type == Constants.ITEM)
|
||||
{
|
||||
Item item = (Item) dso;
|
||||
// @TODO: maybe add an option to apply template Item on ingest??
|
||||
|
||||
//Check if this item is still in a user's workspace.
|
||||
//It should be, as we haven't completed its install yet.
|
||||
WorkspaceItem wsi = WorkspaceItem.findByItem(context, item);
|
||||
|
||||
// Get collection this item is being submitted to
|
||||
Collection collection = item.getOwningCollection();
|
||||
if (collection == null)
|
||||
{
|
||||
// If an item doesn't have an owning-collection, that means it
|
||||
// has entered a workflow (and is not fully in the archive yet)
|
||||
WorkflowItem wfi = WorkflowItem.findByItem(context, item);
|
||||
|
||||
// Get the collection this workflow item belongs to
|
||||
if (wfi != null)
|
||||
// Get the collection this workspace item belongs to
|
||||
if (wsi != null)
|
||||
{
|
||||
collection = wfi.getCollection();
|
||||
collection = wsi.getCollection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,9 +502,14 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester
|
||||
// have subclass manage license since it may be extra package file.
|
||||
addLicense(context, item, license, collection, params);
|
||||
|
||||
// XXX FIXME
|
||||
// should set lastModifiedTime e.g. when ingesting AIP.
|
||||
// maybe only do it in the finishObject() callback for AIP.
|
||||
// Finally, if item is still in the workspace, then we actually need
|
||||
// to install it into the archive & assign its handle.
|
||||
if(wsi!=null)
|
||||
{
|
||||
// Finish creating the item. This actually assigns the handle,
|
||||
// and will either install item immediately or start a workflow, based on params
|
||||
PackageUtils.finishCreateItem(context, wsi, handle, params);
|
||||
}
|
||||
|
||||
} // end if ITEM
|
||||
else if (type == Constants.COLLECTION || type == Constants.COMMUNITY)
|
||||
@@ -519,17 +534,6 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester
|
||||
+ String.valueOf(type));
|
||||
}
|
||||
|
||||
// -- Step 5 --
|
||||
// Run our Descriptive metadata (dublin core, etc) crosswalks!
|
||||
crosswalkObjectDmd(context, dso, manifest, callback, manifest
|
||||
.getItemDmds(), params);
|
||||
|
||||
// For Items, also sanity-check the metadata for minimum requirements.
|
||||
if (type == Constants.ITEM)
|
||||
{
|
||||
PackageUtils.checkItemMetadata((Item) dso);
|
||||
}
|
||||
|
||||
// -- Step 6 --
|
||||
// Finish things up!
|
||||
|
||||
@@ -635,7 +639,6 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester
|
||||
if (dso.getType() == Constants.ITEM)
|
||||
{
|
||||
Item item = (Item) dso;
|
||||
// @TODO: maybe add an option to apply template Item on ingest??
|
||||
|
||||
// save manifest as a bitstream in Item if desired
|
||||
if (preserveManifest())
|
||||
|
@@ -1,191 +1,191 @@
|
||||
/**
|
||||
* 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.content.packager;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.ItemIterator;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An abstract implementation of a DSpace Package Disseminator, which
|
||||
* implements a few helper/utility methods that most (all?) PackageDisseminators
|
||||
* may find useful.
|
||||
* <P>
|
||||
* First, implements recursive functionality in the disseminateAll()
|
||||
* method of the PackageIngester interface. This method is setup to
|
||||
* recursively call disseminate() method.
|
||||
* <P>
|
||||
* All Package disseminators should either extend this abstract class
|
||||
* or implement <code>PackageDisseminator</code> to better suit their needs.
|
||||
*
|
||||
* @author Tim Donohue
|
||||
* @see PackageDisseminator
|
||||
*/
|
||||
public abstract class AbstractPackageDisseminator
|
||||
implements PackageDisseminator
|
||||
{
|
||||
/** List of all successfully disseminated package files */
|
||||
private List<File> packageFileList = new ArrayList<File>();
|
||||
|
||||
/**
|
||||
* Recursively export one or more DSpace Objects as a series of packages.
|
||||
* This method will export the given DSpace Object as well as all referenced
|
||||
* DSpaceObjects (e.g. child objects) into a series of packages. The
|
||||
* initial object is exported to the location specified by the OutputStream.
|
||||
* All other packages are exported to the same directory location.
|
||||
* <p>
|
||||
* Package is any serialized representation of the item, at the discretion
|
||||
* of the implementing class. It does not have to include content bitstreams.
|
||||
* <br>
|
||||
* Use the <code>params</code> parameter list to adjust the way the
|
||||
* package is made, e.g. including a "<code>metadataOnly</code>"
|
||||
* parameter might make the package a bare manifest in XML
|
||||
* instead of a Zip file including manifest and contents.
|
||||
* <br>
|
||||
* Throws an exception of the initial object is not acceptable or there is
|
||||
* a failure creating the package.
|
||||
*
|
||||
* @param context DSpace context.
|
||||
* @param dso initial DSpace object
|
||||
* @param params Properties-style list of options specific to this packager
|
||||
* @param pkgFile File where initial package should be written. All other
|
||||
* packages will be written to the same directory as this File.
|
||||
* @throws PackageValidationException if package cannot be created or there is
|
||||
* a fatal error in creating it.
|
||||
*/
|
||||
@Override
|
||||
public List<File> disseminateAll(Context context, DSpaceObject dso,
|
||||
PackageParameters params, File pkgFile)
|
||||
throws PackageException, CrosswalkException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
//If unset, make sure the Parameters specifies this is a recursive dissemination
|
||||
if(!params.recursiveModeEnabled())
|
||||
{
|
||||
params.setRecursiveModeEnabled(true);
|
||||
}
|
||||
|
||||
//try to disseminate the first object using provided PackageDisseminator
|
||||
disseminate(context, dso, params, pkgFile);
|
||||
|
||||
//check if package was disseminated
|
||||
if(pkgFile.exists())
|
||||
{
|
||||
//add to list of successfully disseminated packages
|
||||
addToPackageList(pkgFile);
|
||||
|
||||
//We can only recursively disseminate non-Items
|
||||
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
|
||||
if(dso.getType()!=Constants.ITEM)
|
||||
{
|
||||
//Determine where first file package was disseminated to, as all
|
||||
//others will be written to same directory
|
||||
String pkgDirectory = pkgFile.getCanonicalFile().getParent();
|
||||
if(!pkgDirectory.endsWith(File.separator))
|
||||
{
|
||||
pkgDirectory += File.separator;
|
||||
}
|
||||
String fileExtension = PackageUtils.getFileExtension(pkgFile.getName());
|
||||
|
||||
//recursively disseminate content, based on object type
|
||||
switch (dso.getType())
|
||||
{
|
||||
case Constants.COLLECTION :
|
||||
//Also find all Items in this Collection and disseminate
|
||||
Collection collection = (Collection) dso;
|
||||
ItemIterator iterator = collection.getItems();
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
Item item = iterator.next();
|
||||
|
||||
//disseminate all items (recursively!)
|
||||
String childFileName = pkgDirectory + PackageUtils.getPackageName(item, fileExtension);
|
||||
disseminateAll(context, item, params, new File(childFileName));
|
||||
}
|
||||
|
||||
break;
|
||||
case Constants.COMMUNITY :
|
||||
//Also find all SubCommunities in this Community and disseminate
|
||||
Community community = (Community) dso;
|
||||
Community[] subcommunities = community.getSubcommunities();
|
||||
for(int i=0; i<subcommunities.length; i++)
|
||||
{
|
||||
//disseminate all sub-communities (recursively!)
|
||||
String childFileName = pkgDirectory + PackageUtils.getPackageName(subcommunities[i], fileExtension);
|
||||
disseminateAll(context, subcommunities[i], params, new File(childFileName));
|
||||
}
|
||||
|
||||
//Also find all Collections in this Community and disseminate
|
||||
Collection[] collections = community.getCollections();
|
||||
for(int i=0; i<collections.length; i++)
|
||||
{
|
||||
//disseminate all collections (recursively!)
|
||||
String childFileName = pkgDirectory + PackageUtils.getPackageName(collections[i], fileExtension);
|
||||
disseminateAll(context, collections[i], params, new File(childFileName));
|
||||
}
|
||||
|
||||
break;
|
||||
case Constants.SITE :
|
||||
//Also find all top-level Communities and disseminate
|
||||
Community[] topCommunities = Community.findAllTop(context);
|
||||
for(int i=0; i<topCommunities.length; i++)
|
||||
{
|
||||
//disseminate all top-level communities (recursively!)
|
||||
String childFileName = pkgDirectory + PackageUtils.getPackageName(topCommunities[i], fileExtension);
|
||||
disseminateAll(context, topCommunities[i], params, new File(childFileName));
|
||||
}
|
||||
|
||||
break;
|
||||
}//end switch
|
||||
}//end if not an Item
|
||||
}//end if pkgFile exists
|
||||
|
||||
//return list of all successfully disseminated packages
|
||||
return getPackageList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add File to list of successfully disseminated package files
|
||||
* @param file File
|
||||
*/
|
||||
protected void addToPackageList(File f)
|
||||
{
|
||||
//add to list of successfully disseminated packages
|
||||
if(!packageFileList.contains(f))
|
||||
{
|
||||
packageFileList.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return List of all package Files which have been disseminated
|
||||
* this instance of the Disseminator.
|
||||
* <P>
|
||||
* This list can be useful in reporting back to the user what content has
|
||||
* been disseminated as packages. It's used by disseminateAll() to report
|
||||
* what packages were created.
|
||||
*
|
||||
* @return List of Files which correspond to the disseminated packages
|
||||
*/
|
||||
protected List<File> getPackageList()
|
||||
{
|
||||
return packageFileList;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.packager;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.ItemIterator;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An abstract implementation of a DSpace Package Disseminator, which
|
||||
* implements a few helper/utility methods that most (all?) PackageDisseminators
|
||||
* may find useful.
|
||||
* <P>
|
||||
* First, implements recursive functionality in the disseminateAll()
|
||||
* method of the PackageIngester interface. This method is setup to
|
||||
* recursively call disseminate() method.
|
||||
* <P>
|
||||
* All Package disseminators should either extend this abstract class
|
||||
* or implement <code>PackageDisseminator</code> to better suit their needs.
|
||||
*
|
||||
* @author Tim Donohue
|
||||
* @see PackageDisseminator
|
||||
*/
|
||||
public abstract class AbstractPackageDisseminator
|
||||
implements PackageDisseminator
|
||||
{
|
||||
/** List of all successfully disseminated package files */
|
||||
private List<File> packageFileList = new ArrayList<File>();
|
||||
|
||||
/**
|
||||
* Recursively export one or more DSpace Objects as a series of packages.
|
||||
* This method will export the given DSpace Object as well as all referenced
|
||||
* DSpaceObjects (e.g. child objects) into a series of packages. The
|
||||
* initial object is exported to the location specified by the OutputStream.
|
||||
* All other packages are exported to the same directory location.
|
||||
* <p>
|
||||
* Package is any serialized representation of the item, at the discretion
|
||||
* of the implementing class. It does not have to include content bitstreams.
|
||||
* <br>
|
||||
* Use the <code>params</code> parameter list to adjust the way the
|
||||
* package is made, e.g. including a "<code>metadataOnly</code>"
|
||||
* parameter might make the package a bare manifest in XML
|
||||
* instead of a Zip file including manifest and contents.
|
||||
* <br>
|
||||
* Throws an exception of the initial object is not acceptable or there is
|
||||
* a failure creating the package.
|
||||
*
|
||||
* @param context DSpace context.
|
||||
* @param dso initial DSpace object
|
||||
* @param params Properties-style list of options specific to this packager
|
||||
* @param pkgFile File where initial package should be written. All other
|
||||
* packages will be written to the same directory as this File.
|
||||
* @throws PackageValidationException if package cannot be created or there is
|
||||
* a fatal error in creating it.
|
||||
*/
|
||||
@Override
|
||||
public List<File> disseminateAll(Context context, DSpaceObject dso,
|
||||
PackageParameters params, File pkgFile)
|
||||
throws PackageException, CrosswalkException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
//If unset, make sure the Parameters specifies this is a recursive dissemination
|
||||
if(!params.recursiveModeEnabled())
|
||||
{
|
||||
params.setRecursiveModeEnabled(true);
|
||||
}
|
||||
|
||||
//try to disseminate the first object using provided PackageDisseminator
|
||||
disseminate(context, dso, params, pkgFile);
|
||||
|
||||
//check if package was disseminated
|
||||
if(pkgFile.exists())
|
||||
{
|
||||
//add to list of successfully disseminated packages
|
||||
addToPackageList(pkgFile);
|
||||
|
||||
//We can only recursively disseminate non-Items
|
||||
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
|
||||
if(dso.getType()!=Constants.ITEM)
|
||||
{
|
||||
//Determine where first file package was disseminated to, as all
|
||||
//others will be written to same directory
|
||||
String pkgDirectory = pkgFile.getCanonicalFile().getParent();
|
||||
if(!pkgDirectory.endsWith(File.separator))
|
||||
{
|
||||
pkgDirectory += File.separator;
|
||||
}
|
||||
String fileExtension = PackageUtils.getFileExtension(pkgFile.getName());
|
||||
|
||||
//recursively disseminate content, based on object type
|
||||
switch (dso.getType())
|
||||
{
|
||||
case Constants.COLLECTION :
|
||||
//Also find all Items in this Collection and disseminate
|
||||
Collection collection = (Collection) dso;
|
||||
ItemIterator iterator = collection.getItems();
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
Item item = iterator.next();
|
||||
|
||||
//disseminate all items (recursively!)
|
||||
String childFileName = pkgDirectory + PackageUtils.getPackageName(item, fileExtension);
|
||||
disseminateAll(context, item, params, new File(childFileName));
|
||||
}
|
||||
|
||||
break;
|
||||
case Constants.COMMUNITY :
|
||||
//Also find all SubCommunities in this Community and disseminate
|
||||
Community community = (Community) dso;
|
||||
Community[] subcommunities = community.getSubcommunities();
|
||||
for(int i=0; i<subcommunities.length; i++)
|
||||
{
|
||||
//disseminate all sub-communities (recursively!)
|
||||
String childFileName = pkgDirectory + PackageUtils.getPackageName(subcommunities[i], fileExtension);
|
||||
disseminateAll(context, subcommunities[i], params, new File(childFileName));
|
||||
}
|
||||
|
||||
//Also find all Collections in this Community and disseminate
|
||||
Collection[] collections = community.getCollections();
|
||||
for(int i=0; i<collections.length; i++)
|
||||
{
|
||||
//disseminate all collections (recursively!)
|
||||
String childFileName = pkgDirectory + PackageUtils.getPackageName(collections[i], fileExtension);
|
||||
disseminateAll(context, collections[i], params, new File(childFileName));
|
||||
}
|
||||
|
||||
break;
|
||||
case Constants.SITE :
|
||||
//Also find all top-level Communities and disseminate
|
||||
Community[] topCommunities = Community.findAllTop(context);
|
||||
for(int i=0; i<topCommunities.length; i++)
|
||||
{
|
||||
//disseminate all top-level communities (recursively!)
|
||||
String childFileName = pkgDirectory + PackageUtils.getPackageName(topCommunities[i], fileExtension);
|
||||
disseminateAll(context, topCommunities[i], params, new File(childFileName));
|
||||
}
|
||||
|
||||
break;
|
||||
}//end switch
|
||||
}//end if not an Item
|
||||
}//end if pkgFile exists
|
||||
|
||||
//return list of all successfully disseminated packages
|
||||
return getPackageList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add File to list of successfully disseminated package files
|
||||
* @param file File
|
||||
*/
|
||||
protected void addToPackageList(File f)
|
||||
{
|
||||
//add to list of successfully disseminated packages
|
||||
if(!packageFileList.contains(f))
|
||||
{
|
||||
packageFileList.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return List of all package Files which have been disseminated
|
||||
* this instance of the Disseminator.
|
||||
* <P>
|
||||
* This list can be useful in reporting back to the user what content has
|
||||
* been disseminated as packages. It's used by disseminateAll() to report
|
||||
* what packages were created.
|
||||
*
|
||||
* @return List of Files which correspond to the disseminated packages
|
||||
*/
|
||||
protected List<File> getPackageList()
|
||||
{
|
||||
return packageFileList;
|
||||
}
|
||||
}
|
||||
|
@@ -1,380 +1,380 @@
|
||||
/**
|
||||
* 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.content.packager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
|
||||
/**
|
||||
* An abstract implementation of a DSpace Package Ingester, which
|
||||
* implements a few helper/utility methods that most (all?) PackageIngesters
|
||||
* may find useful.
|
||||
* <P>
|
||||
* First, implements recursive functionality in ingestAll() and replaceAll()
|
||||
* methods of the PackageIngester interface. These methods are setup to
|
||||
* recursively call ingest() and replace() respectively.
|
||||
* <P>
|
||||
* Finally, it also implements several utility methods (createDSpaceObject(),
|
||||
* finishCreateItem(), updateDSpaceObject()) which subclasses may find useful.
|
||||
* This classes will allow subclasses to easily create/update objects without
|
||||
* having to worry too much about normal DSpace submission workflows (which is
|
||||
* taken care of in these utility methods).
|
||||
* <P>
|
||||
* All Package ingesters should either extend this abstract class
|
||||
* or implement <code>PackageIngester</code> to better suit their needs.
|
||||
*
|
||||
* @author Tim Donohue
|
||||
* @see PackageIngester
|
||||
*/
|
||||
public abstract class AbstractPackageIngester
|
||||
implements PackageIngester
|
||||
{
|
||||
/** log4j category */
|
||||
private static Logger log = Logger.getLogger(AbstractPackageIngester.class);
|
||||
|
||||
/**
|
||||
* References to other packages -- these are the next packages to ingest recursively
|
||||
* Key = DSpace Object just ingested, Value = List of all packages relating to a DSpaceObject
|
||||
**/
|
||||
private Map<DSpaceObject,List<String>> packageReferences = new HashMap<DSpaceObject,List<String>>();
|
||||
|
||||
/** List of all successfully ingested/replaced DSpace objects */
|
||||
private List<DSpaceObject> dsoIngestedList = new ArrayList<DSpaceObject>();
|
||||
|
||||
/**
|
||||
* Recursively create one or more DSpace Objects out of the contents
|
||||
* of the ingested package (and all other referenced packages).
|
||||
* The initial object is created under the indicated parent. All other
|
||||
* objects are created based on their relationship to the initial object.
|
||||
* <p>
|
||||
* For example, a scenario may be to create a Collection based on a
|
||||
* collection-level package, and also create an Item for every item-level
|
||||
* package referenced by the collection-level package.
|
||||
* <p>
|
||||
* The output of this method is one or more newly created <code>DspaceObject<code>s.
|
||||
* <p>
|
||||
* The packager <em>may</em> choose not to implement <code>ingestAll</code>,
|
||||
* or simply forward the call to <code>ingest</code> if it is unable to support
|
||||
* recursive ingestion.
|
||||
* <p>
|
||||
* The deposit license (Only significant for Item) is passed
|
||||
* explicitly as a string since there is no place for it in many
|
||||
* package formats. It is optional and may be given as
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @param context DSpace context.
|
||||
* @param parent parent under which to create the initial object
|
||||
* (may be null -- in which case ingester must determine parent from package
|
||||
* or throw an error).
|
||||
* @param pkgFile The initial package file to ingest
|
||||
* @param params Properties-style list of options (interpreted by each packager).
|
||||
* @param license may be null, which takes default license.
|
||||
* @return List of DSpaceObjects created
|
||||
*
|
||||
* @throws PackageValidationException if initial package (or any referenced package)
|
||||
* is unacceptable or there is a fatal error in creating a DSpaceObject
|
||||
* @throws UnsupportedOperationException if this packager does not
|
||||
* implement <code>ingestAll</code>
|
||||
*/
|
||||
@Override
|
||||
public List<DSpaceObject> ingestAll(Context context, DSpaceObject parent, File pkgFile,
|
||||
PackageParameters params, String license)
|
||||
throws PackageException, UnsupportedOperationException,
|
||||
CrosswalkException, AuthorizeException,
|
||||
SQLException, IOException
|
||||
{
|
||||
//If unset, make sure the Parameters specifies this is a recursive ingest
|
||||
if(!params.recursiveModeEnabled())
|
||||
{
|
||||
params.setRecursiveModeEnabled(true);
|
||||
}
|
||||
|
||||
//Initial DSpace Object to ingest
|
||||
DSpaceObject dso = null;
|
||||
|
||||
//try to ingest the first package
|
||||
try
|
||||
{
|
||||
//actually ingest pkg using provided PackageIngester
|
||||
dso = ingest(context, parent, pkgFile, params, license);
|
||||
}
|
||||
catch(IllegalStateException ie)
|
||||
{
|
||||
// NOTE: if we encounter an IllegalStateException, this means the
|
||||
// handle is already in use and this object already exists.
|
||||
|
||||
//if we are skipping over (i.e. keeping) existing objects
|
||||
if(params.keepExistingModeEnabled())
|
||||
{
|
||||
log.warn(LogManager.getHeader(context, "skip_package_ingest", "Object already exists, package-skipped=" + pkgFile));
|
||||
}
|
||||
else // Pass this exception on -- which essentially causes a full rollback of all changes (this is the default)
|
||||
{
|
||||
throw ie;
|
||||
}
|
||||
}
|
||||
|
||||
//as long as our first object was ingested successfully
|
||||
if(dso!=null)
|
||||
{
|
||||
//add to list of successfully ingested objects
|
||||
addToIngestedList(dso);
|
||||
|
||||
//We can only recursively ingest non-Items
|
||||
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
|
||||
if(dso.getType()!=Constants.ITEM)
|
||||
{
|
||||
//Check if we found child package references when ingesting this latest DSpaceObject
|
||||
List<String> childPkgRefs = getPackageReferences(dso);
|
||||
|
||||
//we can only recursively ingest child packages
|
||||
//if we have references to them
|
||||
if(childPkgRefs!=null && !childPkgRefs.isEmpty())
|
||||
{
|
||||
//Recursively ingest each child package, using this current object as the parent DSpace Object
|
||||
for(String childPkgRef : childPkgRefs)
|
||||
{
|
||||
// Remember where the additions start
|
||||
int oldSize = dsoIngestedList.size();
|
||||
|
||||
//Assume package reference is relative to current package location
|
||||
File childPkg = new File(pkgFile.getAbsoluteFile().getParent(), childPkgRef);
|
||||
|
||||
//fun, it's recursive! -- ingested referenced package as a child of current object
|
||||
ingestAll(context, dso, childPkg, params, license);
|
||||
|
||||
// A Collection can map to Items that it does not "own".
|
||||
// If a Collection package has an Item as a child, it
|
||||
// should be mapped regardless of ownership.
|
||||
// Note: Only perform this mapping if new items were ingested to this collection
|
||||
if (Constants.COLLECTION == dso.getType() && dsoIngestedList.size()>oldSize)
|
||||
{
|
||||
// Since running 'ingestAll' on an item, will only ingest one Item at most,
|
||||
// Just make sure that item is mapped to this collection.
|
||||
Item childItem = (Item)dsoIngestedList.get(oldSize);
|
||||
Collection collection = (Collection)dso;
|
||||
if (!childItem.isIn(collection))
|
||||
{
|
||||
collection.addItem(childItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end if child pkgs
|
||||
}//end if not an Item
|
||||
}//end if DSpaceObject not null
|
||||
|
||||
//Return list of all objects ingested
|
||||
return getIngestedList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively replace one or more DSpace Objects out of the contents
|
||||
* of the ingested package (and all other referenced packages).
|
||||
* The initial object to replace is indicated by <code>dso</code>. All other
|
||||
* objects are replaced based on information provided in the referenced packages.
|
||||
* <p>
|
||||
* For example, a scenario may be to replace a Collection based on a
|
||||
* collection-level package, and also replace *every* Item in that collection
|
||||
* based on the item-level packages referenced by the collection-level package.
|
||||
* <p>
|
||||
* Please note that since the <code>dso</code> input only specifies the
|
||||
* initial object to replace, any additional objects to replace must be
|
||||
* determined based on the referenced packages (or initial package itself).
|
||||
* <p>
|
||||
* The output of this method is one or more replaced <code>DspaceObject<code>s.
|
||||
* <p>
|
||||
* The packager <em>may</em> choose not to implement <code>replaceAll</code>,
|
||||
* since it somewhat contradicts the archival nature of DSpace. It also
|
||||
* may choose to forward the call to <code>replace</code> if it is unable to
|
||||
* support recursive replacement.
|
||||
*
|
||||
* @param context DSpace context.
|
||||
* @param dso initial existing DSpace Object to be replaced, may be null
|
||||
* if object to replace can be determined from package
|
||||
* @param pkgFile The package file to ingest.
|
||||
* @param params Properties-style list of options specific to this packager
|
||||
* @return List of DSpaceObjects replaced
|
||||
*
|
||||
* @throws PackageValidationException if initial package (or any referenced package)
|
||||
* is unacceptable or there is a fatal error in creating a DSpaceObject
|
||||
* @throws UnsupportedOperationException if this packager does not
|
||||
* implement <code>replaceAll</code>
|
||||
*/
|
||||
@Override
|
||||
public List<DSpaceObject> replaceAll(Context context, DSpaceObject dso,
|
||||
File pkgFile, PackageParameters params)
|
||||
throws PackageException, UnsupportedOperationException,
|
||||
CrosswalkException, AuthorizeException,
|
||||
SQLException, IOException
|
||||
{
|
||||
//If unset, make sure the Parameters specifies this is a recursive replace
|
||||
if(!params.recursiveModeEnabled())
|
||||
{
|
||||
params.setRecursiveModeEnabled(true);
|
||||
}
|
||||
|
||||
//actually ingest pkg using provided PackageIngester, and replace object
|
||||
//NOTE: 'dso' may be null! If it is null, the PackageIngester must determine
|
||||
// the object to be replaced from the package itself.
|
||||
DSpaceObject replacedDso = replace(context, dso, pkgFile, params);
|
||||
|
||||
//as long as our object was replaced successfully
|
||||
if(replacedDso!=null)
|
||||
{
|
||||
//add to list of successfully replaced objects
|
||||
addToIngestedList(replacedDso);
|
||||
|
||||
//We can only recursively replace non-Items
|
||||
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
|
||||
if(replacedDso.getType()!=Constants.ITEM)
|
||||
{
|
||||
//Check if we found child package references when replacing this latest DSpaceObject
|
||||
List<String> childPkgRefs = getPackageReferences(replacedDso);
|
||||
|
||||
//we can only recursively ingest child packages
|
||||
//if we have references to them
|
||||
if(childPkgRefs!=null && !childPkgRefs.isEmpty())
|
||||
{
|
||||
//Recursively replace each child package
|
||||
for(String childPkgRef : childPkgRefs)
|
||||
{
|
||||
// Remember where the additions start
|
||||
int oldSize = dsoIngestedList.size();
|
||||
|
||||
//Assume package reference is relative to current package location
|
||||
File childPkg = new File(pkgFile.getAbsoluteFile().getParent(), childPkgRef);
|
||||
|
||||
//fun, it's recursive! -- replaced referenced package as a child of current object
|
||||
// Pass object to replace as 'null', as we don't know which object to replace.
|
||||
replaceAll(context, null, childPkg, params);
|
||||
|
||||
// A Collection can map to Items that it does not "own".
|
||||
// If a Collection package has an Item as a child, it
|
||||
// should be mapped regardless of ownership.
|
||||
|
||||
// If a Collection package has an Item as a child, it
|
||||
// should be mapped regardless of ownership.
|
||||
// Note: Only perform this mapping if new items were ingested to this collection
|
||||
if (Constants.COLLECTION == replacedDso.getType() && dsoIngestedList.size()>oldSize)
|
||||
{
|
||||
// Since running 'replaceAll' on an item, will only ingest one Item at most,
|
||||
// Just make sure that item is mapped to this collection.
|
||||
Item childItem = (Item)dsoIngestedList.get(oldSize);
|
||||
Collection collection = (Collection)replacedDso;
|
||||
if (!childItem.isIn(collection))
|
||||
{
|
||||
collection.addItem(childItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end if child pkgs
|
||||
}//end if not an Item
|
||||
}//end if DSpaceObject not null
|
||||
|
||||
//Return list of all objects replaced
|
||||
return getIngestedList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* During ingestion process, some submission information packages (SIPs)
|
||||
* may reference other packages to be ingested (recursively).
|
||||
* <P>
|
||||
* This method collects all references to other packages, so that we
|
||||
* can choose to recursively ingest them, as necessary, alongside the
|
||||
* DSpaceObject created from the original SIP.
|
||||
* <P>
|
||||
* References are collected based on the DSpaceObject created from the SIP
|
||||
* (this way we keep the context of these references).
|
||||
*
|
||||
* @param dso DSpaceObject whose SIP referenced another package
|
||||
* @param packageRef A reference to another package, which can be ingested after this one
|
||||
*/
|
||||
public void addPackageReference(DSpaceObject dso, String packageRef)
|
||||
{
|
||||
List<String> packageRefValues = null;
|
||||
|
||||
// Check if we already have an entry for packages reference by this object
|
||||
if(packageReferences.containsKey(dso))
|
||||
{
|
||||
packageRefValues = packageReferences.get(dso);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Create a new empty list of references
|
||||
packageRefValues = new ArrayList<String>();
|
||||
}
|
||||
|
||||
//add this package reference to existing list and save
|
||||
packageRefValues.add(packageRef);
|
||||
packageReferences.put(dso, packageRefValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of known SIP references from a newly created DSpaceObject.
|
||||
* <P>
|
||||
* These references should detail where another package exists which
|
||||
* should be ingested alongside the current DSpaceObject.
|
||||
* <P>
|
||||
* The <code>AbstractPackageIngester</code> or an equivalent SIP handler is expected
|
||||
* to understand how to deal with these package references.
|
||||
*
|
||||
* @param dso DSpaceObject whose SIP referenced other SIPs
|
||||
* @return List of Strings which are the references to external submission ingestion packages
|
||||
* (may be null if no SIPs were referenced)
|
||||
*/
|
||||
public List<String> getPackageReferences(DSpaceObject dso)
|
||||
{
|
||||
return packageReferences.get(dso);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DSpaceObject to list of successfully ingested/replaced objects
|
||||
* @param dso DSpaceObject
|
||||
*/
|
||||
protected void addToIngestedList(DSpaceObject dso)
|
||||
{
|
||||
//add to list of successfully ingested objects
|
||||
if(!dsoIngestedList.contains(dso))
|
||||
{
|
||||
dsoIngestedList.add(dso);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return List of all DSpaceObjects which have been ingested/replaced by
|
||||
* this instance of the Ingester.
|
||||
* <P>
|
||||
* This list can be useful in reporting back to the user what content has
|
||||
* been added or replaced. It's used by ingestAll() and replaceAll() to
|
||||
* return this list of everything that was ingested/replaced.
|
||||
*
|
||||
* @return List of DSpaceObjects which have been added/replaced
|
||||
*/
|
||||
protected List<DSpaceObject> getIngestedList()
|
||||
{
|
||||
return dsoIngestedList;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.content.packager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
|
||||
/**
|
||||
* An abstract implementation of a DSpace Package Ingester, which
|
||||
* implements a few helper/utility methods that most (all?) PackageIngesters
|
||||
* may find useful.
|
||||
* <P>
|
||||
* First, implements recursive functionality in ingestAll() and replaceAll()
|
||||
* methods of the PackageIngester interface. These methods are setup to
|
||||
* recursively call ingest() and replace() respectively.
|
||||
* <P>
|
||||
* Finally, it also implements several utility methods (createDSpaceObject(),
|
||||
* finishCreateItem(), updateDSpaceObject()) which subclasses may find useful.
|
||||
* This classes will allow subclasses to easily create/update objects without
|
||||
* having to worry too much about normal DSpace submission workflows (which is
|
||||
* taken care of in these utility methods).
|
||||
* <P>
|
||||
* All Package ingesters should either extend this abstract class
|
||||
* or implement <code>PackageIngester</code> to better suit their needs.
|
||||
*
|
||||
* @author Tim Donohue
|
||||
* @see PackageIngester
|
||||
*/
|
||||
public abstract class AbstractPackageIngester
|
||||
implements PackageIngester
|
||||
{
|
||||
/** log4j category */
|
||||
private static Logger log = Logger.getLogger(AbstractPackageIngester.class);
|
||||
|
||||
/**
|
||||
* References to other packages -- these are the next packages to ingest recursively
|
||||
* Key = DSpace Object just ingested, Value = List of all packages relating to a DSpaceObject
|
||||
**/
|
||||
private Map<DSpaceObject,List<String>> packageReferences = new HashMap<DSpaceObject,List<String>>();
|
||||
|
||||
/** List of all successfully ingested/replaced DSpace objects */
|
||||
private List<DSpaceObject> dsoIngestedList = new ArrayList<DSpaceObject>();
|
||||
|
||||
/**
|
||||
* Recursively create one or more DSpace Objects out of the contents
|
||||
* of the ingested package (and all other referenced packages).
|
||||
* The initial object is created under the indicated parent. All other
|
||||
* objects are created based on their relationship to the initial object.
|
||||
* <p>
|
||||
* For example, a scenario may be to create a Collection based on a
|
||||
* collection-level package, and also create an Item for every item-level
|
||||
* package referenced by the collection-level package.
|
||||
* <p>
|
||||
* The output of this method is one or more newly created <code>DspaceObject<code>s.
|
||||
* <p>
|
||||
* The packager <em>may</em> choose not to implement <code>ingestAll</code>,
|
||||
* or simply forward the call to <code>ingest</code> if it is unable to support
|
||||
* recursive ingestion.
|
||||
* <p>
|
||||
* The deposit license (Only significant for Item) is passed
|
||||
* explicitly as a string since there is no place for it in many
|
||||
* package formats. It is optional and may be given as
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @param context DSpace context.
|
||||
* @param parent parent under which to create the initial object
|
||||
* (may be null -- in which case ingester must determine parent from package
|
||||
* or throw an error).
|
||||
* @param pkgFile The initial package file to ingest
|
||||
* @param params Properties-style list of options (interpreted by each packager).
|
||||
* @param license may be null, which takes default license.
|
||||
* @return List of DSpaceObjects created
|
||||
*
|
||||
* @throws PackageValidationException if initial package (or any referenced package)
|
||||
* is unacceptable or there is a fatal error in creating a DSpaceObject
|
||||
* @throws UnsupportedOperationException if this packager does not
|
||||
* implement <code>ingestAll</code>
|
||||
*/
|
||||
@Override
|
||||
public List<DSpaceObject> ingestAll(Context context, DSpaceObject parent, File pkgFile,
|
||||
PackageParameters params, String license)
|
||||
throws PackageException, UnsupportedOperationException,
|
||||
CrosswalkException, AuthorizeException,
|
||||
SQLException, IOException
|
||||
{
|
||||
//If unset, make sure the Parameters specifies this is a recursive ingest
|
||||
if(!params.recursiveModeEnabled())
|
||||
{
|
||||
params.setRecursiveModeEnabled(true);
|
||||
}
|
||||
|
||||
//Initial DSpace Object to ingest
|
||||
DSpaceObject dso = null;
|
||||
|
||||
//try to ingest the first package
|
||||
try
|
||||
{
|
||||
//actually ingest pkg using provided PackageIngester
|
||||
dso = ingest(context, parent, pkgFile, params, license);
|
||||
}
|
||||
catch(IllegalStateException ie)
|
||||
{
|
||||
// NOTE: if we encounter an IllegalStateException, this means the
|
||||
// handle is already in use and this object already exists.
|
||||
|
||||
//if we are skipping over (i.e. keeping) existing objects
|
||||
if(params.keepExistingModeEnabled())
|
||||
{
|
||||
log.warn(LogManager.getHeader(context, "skip_package_ingest", "Object already exists, package-skipped=" + pkgFile));
|
||||
}
|
||||
else // Pass this exception on -- which essentially causes a full rollback of all changes (this is the default)
|
||||
{
|
||||
throw ie;
|
||||
}
|
||||
}
|
||||
|
||||
//as long as our first object was ingested successfully
|
||||
if(dso!=null)
|
||||
{
|
||||
//add to list of successfully ingested objects
|
||||
addToIngestedList(dso);
|
||||
|
||||
//We can only recursively ingest non-Items
|
||||
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
|
||||
if(dso.getType()!=Constants.ITEM)
|
||||
{
|
||||
//Check if we found child package references when ingesting this latest DSpaceObject
|
||||
List<String> childPkgRefs = getPackageReferences(dso);
|
||||
|
||||
//we can only recursively ingest child packages
|
||||
//if we have references to them
|
||||
if(childPkgRefs!=null && !childPkgRefs.isEmpty())
|
||||
{
|
||||
//Recursively ingest each child package, using this current object as the parent DSpace Object
|
||||
for(String childPkgRef : childPkgRefs)
|
||||
{
|
||||
// Remember where the additions start
|
||||
int oldSize = dsoIngestedList.size();
|
||||
|
||||
//Assume package reference is relative to current package location
|
||||
File childPkg = new File(pkgFile.getAbsoluteFile().getParent(), childPkgRef);
|
||||
|
||||
//fun, it's recursive! -- ingested referenced package as a child of current object
|
||||
ingestAll(context, dso, childPkg, params, license);
|
||||
|
||||
// A Collection can map to Items that it does not "own".
|
||||
// If a Collection package has an Item as a child, it
|
||||
// should be mapped regardless of ownership.
|
||||
// Note: Only perform this mapping if new items were ingested to this collection
|
||||
if (Constants.COLLECTION == dso.getType() && dsoIngestedList.size()>oldSize)
|
||||
{
|
||||
// Since running 'ingestAll' on an item, will only ingest one Item at most,
|
||||
// Just make sure that item is mapped to this collection.
|
||||
Item childItem = (Item)dsoIngestedList.get(oldSize);
|
||||
Collection collection = (Collection)dso;
|
||||
if (!childItem.isIn(collection))
|
||||
{
|
||||
collection.addItem(childItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end if child pkgs
|
||||
}//end if not an Item
|
||||
}//end if DSpaceObject not null
|
||||
|
||||
//Return list of all objects ingested
|
||||
return getIngestedList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively replace one or more DSpace Objects out of the contents
|
||||
* of the ingested package (and all other referenced packages).
|
||||
* The initial object to replace is indicated by <code>dso</code>. All other
|
||||
* objects are replaced based on information provided in the referenced packages.
|
||||
* <p>
|
||||
* For example, a scenario may be to replace a Collection based on a
|
||||
* collection-level package, and also replace *every* Item in that collection
|
||||
* based on the item-level packages referenced by the collection-level package.
|
||||
* <p>
|
||||
* Please note that since the <code>dso</code> input only specifies the
|
||||
* initial object to replace, any additional objects to replace must be
|
||||
* determined based on the referenced packages (or initial package itself).
|
||||
* <p>
|
||||
* The output of this method is one or more replaced <code>DspaceObject<code>s.
|
||||
* <p>
|
||||
* The packager <em>may</em> choose not to implement <code>replaceAll</code>,
|
||||
* since it somewhat contradicts the archival nature of DSpace. It also
|
||||
* may choose to forward the call to <code>replace</code> if it is unable to
|
||||
* support recursive replacement.
|
||||
*
|
||||
* @param context DSpace context.
|
||||
* @param dso initial existing DSpace Object to be replaced, may be null
|
||||
* if object to replace can be determined from package
|
||||
* @param pkgFile The package file to ingest.
|
||||
* @param params Properties-style list of options specific to this packager
|
||||
* @return List of DSpaceObjects replaced
|
||||
*
|
||||
* @throws PackageValidationException if initial package (or any referenced package)
|
||||
* is unacceptable or there is a fatal error in creating a DSpaceObject
|
||||
* @throws UnsupportedOperationException if this packager does not
|
||||
* implement <code>replaceAll</code>
|
||||
*/
|
||||
@Override
|
||||
public List<DSpaceObject> replaceAll(Context context, DSpaceObject dso,
|
||||
File pkgFile, PackageParameters params)
|
||||
throws PackageException, UnsupportedOperationException,
|
||||
CrosswalkException, AuthorizeException,
|
||||
SQLException, IOException
|
||||
{
|
||||
//If unset, make sure the Parameters specifies this is a recursive replace
|
||||
if(!params.recursiveModeEnabled())
|
||||
{
|
||||
params.setRecursiveModeEnabled(true);
|
||||
}
|
||||
|
||||
//actually ingest pkg using provided PackageIngester, and replace object
|
||||
//NOTE: 'dso' may be null! If it is null, the PackageIngester must determine
|
||||
// the object to be replaced from the package itself.
|
||||
DSpaceObject replacedDso = replace(context, dso, pkgFile, params);
|
||||
|
||||
//as long as our object was replaced successfully
|
||||
if(replacedDso!=null)
|
||||
{
|
||||
//add to list of successfully replaced objects
|
||||
addToIngestedList(replacedDso);
|
||||
|
||||
//We can only recursively replace non-Items
|
||||
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
|
||||
if(replacedDso.getType()!=Constants.ITEM)
|
||||
{
|
||||
//Check if we found child package references when replacing this latest DSpaceObject
|
||||
List<String> childPkgRefs = getPackageReferences(replacedDso);
|
||||
|
||||
//we can only recursively ingest child packages
|
||||
//if we have references to them
|
||||
if(childPkgRefs!=null && !childPkgRefs.isEmpty())
|
||||
{
|
||||
//Recursively replace each child package
|
||||
for(String childPkgRef : childPkgRefs)
|
||||
{
|
||||
// Remember where the additions start
|
||||
int oldSize = dsoIngestedList.size();
|
||||
|
||||
//Assume package reference is relative to current package location
|
||||
File childPkg = new File(pkgFile.getAbsoluteFile().getParent(), childPkgRef);
|
||||
|
||||
//fun, it's recursive! -- replaced referenced package as a child of current object
|
||||
// Pass object to replace as 'null', as we don't know which object to replace.
|
||||
replaceAll(context, null, childPkg, params);
|
||||
|
||||
// A Collection can map to Items that it does not "own".
|
||||
// If a Collection package has an Item as a child, it
|
||||
// should be mapped regardless of ownership.
|
||||
|
||||
// If a Collection package has an Item as a child, it
|
||||
// should be mapped regardless of ownership.
|
||||
// Note: Only perform this mapping if new items were ingested to this collection
|
||||
if (Constants.COLLECTION == replacedDso.getType() && dsoIngestedList.size()>oldSize)
|
||||
{
|
||||
// Since running 'replaceAll' on an item, will only ingest one Item at most,
|
||||
// Just make sure that item is mapped to this collection.
|
||||
Item childItem = (Item)dsoIngestedList.get(oldSize);
|
||||
Collection collection = (Collection)replacedDso;
|
||||
if (!childItem.isIn(collection))
|
||||
{
|
||||
collection.addItem(childItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end if child pkgs
|
||||
}//end if not an Item
|
||||
}//end if DSpaceObject not null
|
||||
|
||||
//Return list of all objects replaced
|
||||
return getIngestedList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* During ingestion process, some submission information packages (SIPs)
|
||||
* may reference other packages to be ingested (recursively).
|
||||
* <P>
|
||||
* This method collects all references to other packages, so that we
|
||||
* can choose to recursively ingest them, as necessary, alongside the
|
||||
* DSpaceObject created from the original SIP.
|
||||
* <P>
|
||||
* References are collected based on the DSpaceObject created from the SIP
|
||||
* (this way we keep the context of these references).
|
||||
*
|
||||
* @param dso DSpaceObject whose SIP referenced another package
|
||||
* @param packageRef A reference to another package, which can be ingested after this one
|
||||
*/
|
||||
public void addPackageReference(DSpaceObject dso, String packageRef)
|
||||
{
|
||||
List<String> packageRefValues = null;
|
||||
|
||||
// Check if we already have an entry for packages reference by this object
|
||||
if(packageReferences.containsKey(dso))
|
||||
{
|
||||
packageRefValues = packageReferences.get(dso);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Create a new empty list of references
|
||||
packageRefValues = new ArrayList<String>();
|
||||
}
|
||||
|
||||
//add this package reference to existing list and save
|
||||
packageRefValues.add(packageRef);
|
||||
packageReferences.put(dso, packageRefValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of known SIP references from a newly created DSpaceObject.
|
||||
* <P>
|
||||
* These references should detail where another package exists which
|
||||
* should be ingested alongside the current DSpaceObject.
|
||||
* <P>
|
||||
* The <code>AbstractPackageIngester</code> or an equivalent SIP handler is expected
|
||||
* to understand how to deal with these package references.
|
||||
*
|
||||
* @param dso DSpaceObject whose SIP referenced other SIPs
|
||||
* @return List of Strings which are the references to external submission ingestion packages
|
||||
* (may be null if no SIPs were referenced)
|
||||
*/
|
||||
public List<String> getPackageReferences(DSpaceObject dso)
|
||||
{
|
||||
return packageReferences.get(dso);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DSpaceObject to list of successfully ingested/replaced objects
|
||||
* @param dso DSpaceObject
|
||||
*/
|
||||
protected void addToIngestedList(DSpaceObject dso)
|
||||
{
|
||||
//add to list of successfully ingested objects
|
||||
if(!dsoIngestedList.contains(dso))
|
||||
{
|
||||
dsoIngestedList.add(dso);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return List of all DSpaceObjects which have been ingested/replaced by
|
||||
* this instance of the Ingester.
|
||||
* <P>
|
||||
* This list can be useful in reporting back to the user what content has
|
||||
* been added or replaced. It's used by ingestAll() and replaceAll() to
|
||||
* return this list of everything that was ingested/replaced.
|
||||
*
|
||||
* @return List of DSpaceObjects which have been added/replaced
|
||||
*/
|
||||
protected List<DSpaceObject> getIngestedList()
|
||||
{
|
||||
return dsoIngestedList;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,406 +1,406 @@
|
||||
/**
|
||||
* 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.content.packager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.jdom.Element;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.NonUniqueMetadataException;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
import org.dspace.content.crosswalk.MetadataValidationException;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Constants;
|
||||
|
||||
/**
|
||||
* Subclass of the METS packager framework to ingest a DSpace
|
||||
* Archival Information Package (AIP). The AIP is intended to be, foremost,
|
||||
* a _complete_ and _accurate_ representation of one object in the DSpace
|
||||
* object model. An AIP contains all of the information needed to restore
|
||||
* the object precisely in another DSpace archive instance.
|
||||
* <p>
|
||||
* This ingester recognizes two distinct types of AIPs: "Manifest-Only" and "External".
|
||||
* The Manifest-Only AIP, which is selected by specifying a PackageParameters
|
||||
* key "manifestOnly" with the value "true", refers to all its contents by
|
||||
* reference only. For Community or Collection AIPs this means all references to their
|
||||
* child objects are just via Handles. For Item AIPs all Bitreams are just
|
||||
* referenced by their asset store location instead of finding them in the "package".
|
||||
* The Manifest-Only AIP package format is simply a METS XML document serialized into a file.
|
||||
* <p>
|
||||
* An "external" AIP (the default), is a conventional Zip-file based package
|
||||
* that includes copies of all bitstreams referenced by the object as well
|
||||
* as a serialized METS XML document in the path "mets.xml".
|
||||
*
|
||||
* Configuration keys:
|
||||
*
|
||||
* # instructs which xwalk plugin to use for a given type of metadata
|
||||
* mets.dspaceAIP.ingest.crosswalk.{mdSecName} = {pluginName}
|
||||
* mets.dspaceAIP.ingest.crosswalk.DC = QDC
|
||||
* mets.dspaceAIP.ingest.crosswalk.DSpaceDepositLicense = NULLSTREAM
|
||||
*
|
||||
* # Option to save METS manifest in the item: (default is false)
|
||||
* mets.default.ingest.preserveManifest = false
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @author Tim Donohue
|
||||
* @version $Revision: 1.1 $
|
||||
*
|
||||
* @see AbstractMETSIngester
|
||||
* @see AbstractPackageIngester
|
||||
* @see PackageIngester
|
||||
* @see org.dspace.content.packager.METSManifest
|
||||
*/
|
||||
public class DSpaceAIPIngester
|
||||
extends AbstractMETSIngester
|
||||
{
|
||||
/** log4j category */
|
||||
private static Logger log = Logger.getLogger(DSpaceAIPIngester.class);
|
||||
|
||||
/**
|
||||
* Ensure it's an AIP generated by the complementary AIP disseminator.
|
||||
*/
|
||||
@Override
|
||||
void checkManifest(METSManifest manifest)
|
||||
throws MetadataValidationException
|
||||
{
|
||||
String profile = manifest.getProfile();
|
||||
if (profile == null)
|
||||
{
|
||||
throw new MetadataValidationException("Cannot accept METS with no PROFILE attribute!");
|
||||
}
|
||||
else if (!profile.equals(DSpaceAIPDisseminator.PROFILE_1_0))
|
||||
{
|
||||
throw new MetadataValidationException("METS has unacceptable PROFILE attribute, profile=" + profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Choose DMD section(s) to crosswalk.
|
||||
* <p>
|
||||
* The algorithm is:<br>
|
||||
* 1. Use whatever the <code>dmd</code> parameter specifies as the primary DMD.<br>
|
||||
* 2. If (1) is unspecified, find DIM (preferably) or MODS as primary DMD.<br>
|
||||
* 3. If (1) or (2) succeeds, crosswalk it and ignore all other DMDs with
|
||||
* same GROUPID<br>
|
||||
* 4. Crosswalk remaining DMDs not eliminated already.
|
||||
*/
|
||||
@Override
|
||||
public void crosswalkObjectDmd(Context context, DSpaceObject dso,
|
||||
METSManifest manifest,
|
||||
MdrefManager callback,
|
||||
Element dmds[], PackageParameters params)
|
||||
throws CrosswalkException, PackageValidationException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
int found = -1;
|
||||
|
||||
// Check to see what dmdSec the user specified in the 'dmd' parameter
|
||||
String userDmd = null;
|
||||
if (params != null)
|
||||
{
|
||||
userDmd = params.getProperty("dmd");
|
||||
}
|
||||
if (userDmd != null && userDmd.length() > 0)
|
||||
{
|
||||
for (int i = 0; i < dmds.length; ++i)
|
||||
{
|
||||
if (userDmd.equalsIgnoreCase(manifest.getMdType(dmds[i])))
|
||||
{
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DIM is preferred, if nothing specified by user
|
||||
if (found == -1)
|
||||
{
|
||||
// DIM is preferred for AIP
|
||||
for (int i = 0; i < dmds.length; ++i)
|
||||
{
|
||||
//NOTE: METS standard actually says this should be DIM (all uppercase). But,
|
||||
// just in case, we're going to be a bit more forgiving.
|
||||
if ("DIM".equalsIgnoreCase(manifest.getMdType(dmds[i])))
|
||||
{
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MODS is acceptable otehrwise..
|
||||
if (found == -1)
|
||||
{
|
||||
for (int i = 0; i < dmds.length; ++i)
|
||||
{
|
||||
//NOTE: METS standard actually says this should be MODS (all uppercase). But,
|
||||
// just in case, we're going to be a bit more forgiving.
|
||||
if ("MODS".equalsIgnoreCase(manifest.getMdType(dmds[i])))
|
||||
{
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String groupID = null;
|
||||
if (found >= 0)
|
||||
{
|
||||
manifest.crosswalkItemDmd(context, params, dso, dmds[found], callback);
|
||||
groupID = dmds[found].getAttributeValue("GROUPID");
|
||||
|
||||
if (groupID != null)
|
||||
{
|
||||
for (int i = 0; i < dmds.length; ++i)
|
||||
{
|
||||
String g = dmds[i].getAttributeValue("GROUPID");
|
||||
if (g != null && !g.equals(groupID))
|
||||
{
|
||||
manifest.crosswalkItemDmd(context, params, dso, dmds[i], callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise take the first. Don't xwalk more than one because
|
||||
// each xwalk _adds_ metadata, and could add duplicate fields.
|
||||
else if (dmds.length > 0)
|
||||
{
|
||||
manifest.crosswalkItemDmd(context, params, dso, dmds[0], callback);
|
||||
}
|
||||
|
||||
// it's an error if there is nothing to crosswalk:
|
||||
else
|
||||
{
|
||||
throw new MetadataValidationException("DSpaceAIPIngester: Could not find an acceptable object-wide DMD section in manifest.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ignore license when restoring an manifest-only AIP, since it should
|
||||
* be a bitstream in the AIP already.
|
||||
* Otherwise: Check item for license first; then, take deposit
|
||||
* license supplied by explicit argument next, else use collection's
|
||||
* default deposit license.
|
||||
* Normally the rightsMD crosswalks should provide a license.
|
||||
*/
|
||||
@Override
|
||||
public void addLicense(Context context, Item item, String license,
|
||||
Collection collection, PackageParameters params)
|
||||
throws PackageValidationException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
boolean newLicense = false;
|
||||
|
||||
if(!params.restoreModeEnabled())
|
||||
{
|
||||
//AIP is not being restored/replaced, so treat it like a SIP -- every new SIP needs a new license
|
||||
newLicense = true;
|
||||
}
|
||||
|
||||
// Add deposit license if there isn't one in the object,
|
||||
// and it's not a restoration of an "manifestOnly" AIP:
|
||||
if (!params.getBooleanProperty("manifestOnly", false) &&
|
||||
PackageUtils.findDepositLicense(context, item) == null)
|
||||
{
|
||||
newLicense = true;
|
||||
}
|
||||
|
||||
if(newLicense)
|
||||
{
|
||||
PackageUtils.addDepositLicense(context, license, item, collection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Last change to fix up a DSpace Object.
|
||||
* <P>
|
||||
* For AIPs, if the object is an Item, we may want to make sure all of its
|
||||
* metadata fields already exist in the database (otherwise, the database
|
||||
* will throw errors when we attempt to save/update the Item)
|
||||
*
|
||||
* @param context DSpace Context
|
||||
* @param dso DSpace object
|
||||
* @param params Packager Parameters
|
||||
*/
|
||||
@Override
|
||||
public void finishObject(Context context, DSpaceObject dso, PackageParameters params)
|
||||
throws PackageValidationException, CrosswalkException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
if(dso.getType()==Constants.ITEM)
|
||||
{
|
||||
// Check if 'createMetadataFields' option is enabled (default=true)
|
||||
// This defaults to true as by default we should attempt to restore as much metadata as we can.
|
||||
// When 'createMetadataFields' is set to false, an ingest will fail if it attempts to ingest content to a missing metadata field.
|
||||
if (params.getBooleanProperty("createMetadataFields", true))
|
||||
{
|
||||
// We want to verify that all the Metadata Fields we've crosswalked
|
||||
// actually *exist* in the DB. If not, we'll try to create them
|
||||
createMissingMetadataFields(context, (Item) dso);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nothing extra to do to bitstream after ingestion.
|
||||
*/
|
||||
@Override
|
||||
public void finishBitstream(Context context,
|
||||
Bitstream bs,
|
||||
Element mfile,
|
||||
METSManifest manifest,
|
||||
PackageParameters params)
|
||||
throws MetadataValidationException, SQLException, AuthorizeException, IOException
|
||||
{
|
||||
// nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of DSpaceObject in this package; it is
|
||||
* in the TYPE attribute of the mets:mets element.
|
||||
*/
|
||||
@Override
|
||||
public int getObjectType(METSManifest manifest)
|
||||
throws PackageValidationException
|
||||
{
|
||||
Element mets = manifest.getMets();
|
||||
String typeStr = mets.getAttributeValue("TYPE");
|
||||
if (typeStr == null || typeStr.length() == 0)
|
||||
{
|
||||
throw new PackageValidationException("Manifest is missing the required mets@TYPE attribute.");
|
||||
}
|
||||
if (typeStr.startsWith("DSpace "))
|
||||
{
|
||||
typeStr = typeStr.substring(7);
|
||||
}
|
||||
int type = Constants.getTypeID(typeStr);
|
||||
if (type < 0)
|
||||
{
|
||||
throw new PackageValidationException("Manifest has unrecognized value in mets@TYPE attribute: " + typeStr);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name used to distinguish DSpace Configuration entries for this subclass.
|
||||
*/
|
||||
@Override
|
||||
public String getConfigurationName()
|
||||
{
|
||||
return "dspaceAIP";
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that all the unsaved, crosswalked metadata fields that have
|
||||
* been added to an Item actually exist in our Database. If they don't
|
||||
* exist, they are created within the proper database tables.
|
||||
* <P>
|
||||
* This method must be called *before* item.update(), as the call to update()
|
||||
* will throw a SQLException when attempting to save any fields which
|
||||
* don't already exist in the database.
|
||||
* <P>
|
||||
* NOTE: This will NOT create a missing Metadata Schema (e.g. "dc" schema),
|
||||
* as we do not have enough info to create schemas on the fly.
|
||||
*
|
||||
* @param context - DSpace Context
|
||||
* @param item - Item whose unsaved metadata fields we are testing
|
||||
* @throws AuthorizeException if a metadata field doesn't exist and current user is not authorized to create it (i.e. not an Admin)
|
||||
* @throws PackageValidationException if a metadata schema doesn't exist, as we cannot autocreate a schema
|
||||
*/
|
||||
protected static void createMissingMetadataFields(Context context, Item item)
|
||||
throws PackageValidationException, AuthorizeException, IOException, SQLException
|
||||
{
|
||||
// Get all metadata fields/values currently added to this Item
|
||||
DCValue allMD[] = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||
|
||||
// For each field, we'll check if it exists. If not, we'll create it.
|
||||
for(DCValue md : allMD)
|
||||
{
|
||||
MetadataSchema mdSchema = null;
|
||||
MetadataField mdField = null;
|
||||
try
|
||||
{
|
||||
//Try to access this Schema
|
||||
mdSchema = MetadataSchema.find(context, md.schema);
|
||||
//If Schema found, try to locate field from database
|
||||
if(mdSchema!=null)
|
||||
{
|
||||
mdField = MetadataField.findByElement(context, mdSchema.getSchemaID(), md.element, md.qualifier);
|
||||
}
|
||||
}
|
||||
catch(SQLException se)
|
||||
{
|
||||
//If a SQLException error is thrown, then this field does NOT exist in DB
|
||||
//Set field to null, so we know we need to create it
|
||||
mdField = null;
|
||||
}
|
||||
|
||||
// If our Schema was not found, we have a problem
|
||||
// We cannot easily create a Schema automatically -- as we don't know its Namespace
|
||||
if(mdSchema==null)
|
||||
{
|
||||
throw new PackageValidationException("Unknown Metadata Schema encountered (" + md.schema + ") when attempting to ingest an Item. You will need to create this Metadata Schema in DSpace Schema Registry before the Item can be ingested.");
|
||||
}
|
||||
|
||||
// If our Metadata Field is null, we will attempt to create it in the proper Schema
|
||||
if(mdField==null)
|
||||
{
|
||||
try
|
||||
{
|
||||
//initialize field (but don't set a scope note) & create it
|
||||
mdField = new MetadataField(mdSchema, md.element, md.qualifier, null);
|
||||
// NOTE: Only Adminstrators can create Metadata Fields -- create() will throw an AuthorizationException for non-Admins
|
||||
mdField.create(context);
|
||||
//log that field was created
|
||||
log.info("Located a missing metadata field (schema:'" + mdSchema.getName() +"', element:'"+ md.element +"', qualifier:'"+ md.qualifier +"') while ingesting Item. This missing field has been created in the DSpace Metadata Field Registry.");
|
||||
}
|
||||
catch(NonUniqueMetadataException ne)
|
||||
{ // This exception should never happen, as we already checked to make sure the field doesn't exist.
|
||||
// But, we'll catch it anyways so that the Java compiler doesn't get upset
|
||||
throw new SQLException("Unable to create Metadata Field (element='" + md.element + "', qualifier='" + md.qualifier + "') in Schema "+ mdSchema.getName() +".", ne);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a user help string which should describe the
|
||||
* additional valid command-line options that this packager
|
||||
* implementation will accept when using the <code>-o</code> or
|
||||
* <code>--option</code> flags with the Packager script.
|
||||
*
|
||||
* @return a string describing additional command-line options available
|
||||
* with this packager
|
||||
*/
|
||||
@Override
|
||||
public String getParameterHelp()
|
||||
{
|
||||
String parentHelp = super.getParameterHelp();
|
||||
|
||||
//Return superclass help info, plus the extra parameters/options that this class supports
|
||||
return parentHelp +
|
||||
"\n\n" +
|
||||
"* createMetadataFields=[boolean] " +
|
||||
"If true, ingest attempts to create any missing metadata fields." +
|
||||
"If false, ingest will fail if a metadata field is encountered which doesn't already exist. (default = true)" +
|
||||
"\n\n" +
|
||||
"* dmd=[dmdSecType] " +
|
||||
"Type of the METS <dmdSec> which should be used to restore item metadata (defaults to DIM, then MODS)";
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 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.content.packager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.jdom.Element;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.MetadataField;
|
||||
import org.dspace.content.MetadataSchema;
|
||||
import org.dspace.content.NonUniqueMetadataException;
|
||||
import org.dspace.content.crosswalk.CrosswalkException;
|
||||
import org.dspace.content.crosswalk.MetadataValidationException;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Constants;
|
||||
|
||||
/**
|
||||
* Subclass of the METS packager framework to ingest a DSpace
|
||||
* Archival Information Package (AIP). The AIP is intended to be, foremost,
|
||||
* a _complete_ and _accurate_ representation of one object in the DSpace
|
||||
* object model. An AIP contains all of the information needed to restore
|
||||
* the object precisely in another DSpace archive instance.
|
||||
* <p>
|
||||
* This ingester recognizes two distinct types of AIPs: "Manifest-Only" and "External".
|
||||
* The Manifest-Only AIP, which is selected by specifying a PackageParameters
|
||||
* key "manifestOnly" with the value "true", refers to all its contents by
|
||||
* reference only. For Community or Collection AIPs this means all references to their
|
||||
* child objects are just via Handles. For Item AIPs all Bitreams are just
|
||||
* referenced by their asset store location instead of finding them in the "package".
|
||||
* The Manifest-Only AIP package format is simply a METS XML document serialized into a file.
|
||||
* <p>
|
||||
* An "external" AIP (the default), is a conventional Zip-file based package
|
||||
* that includes copies of all bitstreams referenced by the object as well
|
||||
* as a serialized METS XML document in the path "mets.xml".
|
||||
*
|
||||
* Configuration keys:
|
||||
*
|
||||
* # instructs which xwalk plugin to use for a given type of metadata
|
||||
* mets.dspaceAIP.ingest.crosswalk.{mdSecName} = {pluginName}
|
||||
* mets.dspaceAIP.ingest.crosswalk.DC = QDC
|
||||
* mets.dspaceAIP.ingest.crosswalk.DSpaceDepositLicense = NULLSTREAM
|
||||
*
|
||||
* # Option to save METS manifest in the item: (default is false)
|
||||
* mets.default.ingest.preserveManifest = false
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @author Tim Donohue
|
||||
* @version $Revision: 1.1 $
|
||||
*
|
||||
* @see AbstractMETSIngester
|
||||
* @see AbstractPackageIngester
|
||||
* @see PackageIngester
|
||||
* @see org.dspace.content.packager.METSManifest
|
||||
*/
|
||||
public class DSpaceAIPIngester
|
||||
extends AbstractMETSIngester
|
||||
{
|
||||
/** log4j category */
|
||||
private static Logger log = Logger.getLogger(DSpaceAIPIngester.class);
|
||||
|
||||
/**
|
||||
* Ensure it's an AIP generated by the complementary AIP disseminator.
|
||||
*/
|
||||
@Override
|
||||
void checkManifest(METSManifest manifest)
|
||||
throws MetadataValidationException
|
||||
{
|
||||
String profile = manifest.getProfile();
|
||||
if (profile == null)
|
||||
{
|
||||
throw new MetadataValidationException("Cannot accept METS with no PROFILE attribute!");
|
||||
}
|
||||
else if (!profile.equals(DSpaceAIPDisseminator.PROFILE_1_0))
|
||||
{
|
||||
throw new MetadataValidationException("METS has unacceptable PROFILE attribute, profile=" + profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Choose DMD section(s) to crosswalk.
|
||||
* <p>
|
||||
* The algorithm is:<br>
|
||||
* 1. Use whatever the <code>dmd</code> parameter specifies as the primary DMD.<br>
|
||||
* 2. If (1) is unspecified, find DIM (preferably) or MODS as primary DMD.<br>
|
||||
* 3. If (1) or (2) succeeds, crosswalk it and ignore all other DMDs with
|
||||
* same GROUPID<br>
|
||||
* 4. Crosswalk remaining DMDs not eliminated already.
|
||||
*/
|
||||
@Override
|
||||
public void crosswalkObjectDmd(Context context, DSpaceObject dso,
|
||||
METSManifest manifest,
|
||||
MdrefManager callback,
|
||||
Element dmds[], PackageParameters params)
|
||||
throws CrosswalkException, PackageValidationException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
int found = -1;
|
||||
|
||||
// Check to see what dmdSec the user specified in the 'dmd' parameter
|
||||
String userDmd = null;
|
||||
if (params != null)
|
||||
{
|
||||
userDmd = params.getProperty("dmd");
|
||||
}
|
||||
if (userDmd != null && userDmd.length() > 0)
|
||||
{
|
||||
for (int i = 0; i < dmds.length; ++i)
|
||||
{
|
||||
if (userDmd.equalsIgnoreCase(manifest.getMdType(dmds[i])))
|
||||
{
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DIM is preferred, if nothing specified by user
|
||||
if (found == -1)
|
||||
{
|
||||
// DIM is preferred for AIP
|
||||
for (int i = 0; i < dmds.length; ++i)
|
||||
{
|
||||
//NOTE: METS standard actually says this should be DIM (all uppercase). But,
|
||||
// just in case, we're going to be a bit more forgiving.
|
||||
if ("DIM".equalsIgnoreCase(manifest.getMdType(dmds[i])))
|
||||
{
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MODS is acceptable otehrwise..
|
||||
if (found == -1)
|
||||
{
|
||||
for (int i = 0; i < dmds.length; ++i)
|
||||
{
|
||||
//NOTE: METS standard actually says this should be MODS (all uppercase). But,
|
||||
// just in case, we're going to be a bit more forgiving.
|
||||
if ("MODS".equalsIgnoreCase(manifest.getMdType(dmds[i])))
|
||||
{
|
||||
found = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String groupID = null;
|
||||
if (found >= 0)
|
||||
{
|
||||
manifest.crosswalkItemDmd(context, params, dso, dmds[found], callback);
|
||||
groupID = dmds[found].getAttributeValue("GROUPID");
|
||||
|
||||
if (groupID != null)
|
||||
{
|
||||
for (int i = 0; i < dmds.length; ++i)
|
||||
{
|
||||
String g = dmds[i].getAttributeValue("GROUPID");
|
||||
if (g != null && !g.equals(groupID))
|
||||
{
|
||||
manifest.crosswalkItemDmd(context, params, dso, dmds[i], callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise take the first. Don't xwalk more than one because
|
||||
// each xwalk _adds_ metadata, and could add duplicate fields.
|
||||
else if (dmds.length > 0)
|
||||
{
|
||||
manifest.crosswalkItemDmd(context, params, dso, dmds[0], callback);
|
||||
}
|
||||
|
||||
// it's an error if there is nothing to crosswalk:
|
||||
else
|
||||
{
|
||||
throw new MetadataValidationException("DSpaceAIPIngester: Could not find an acceptable object-wide DMD section in manifest.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ignore license when restoring an manifest-only AIP, since it should
|
||||
* be a bitstream in the AIP already.
|
||||
* Otherwise: Check item for license first; then, take deposit
|
||||
* license supplied by explicit argument next, else use collection's
|
||||
* default deposit license.
|
||||
* Normally the rightsMD crosswalks should provide a license.
|
||||
*/
|
||||
@Override
|
||||
public void addLicense(Context context, Item item, String license,
|
||||
Collection collection, PackageParameters params)
|
||||
throws PackageValidationException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
boolean newLicense = false;
|
||||
|
||||
if(!params.restoreModeEnabled())
|
||||
{
|
||||
//AIP is not being restored/replaced, so treat it like a SIP -- every new SIP needs a new license
|
||||
newLicense = true;
|
||||
}
|
||||
|
||||
// Add deposit license if there isn't one in the object,
|
||||
// and it's not a restoration of an "manifestOnly" AIP:
|
||||
if (!params.getBooleanProperty("manifestOnly", false) &&
|
||||
PackageUtils.findDepositLicense(context, item) == null)
|
||||
{
|
||||
newLicense = true;
|
||||
}
|
||||
|
||||
if(newLicense)
|
||||
{
|
||||
PackageUtils.addDepositLicense(context, license, item, collection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Last change to fix up a DSpace Object.
|
||||
* <P>
|
||||
* For AIPs, if the object is an Item, we may want to make sure all of its
|
||||
* metadata fields already exist in the database (otherwise, the database
|
||||
* will throw errors when we attempt to save/update the Item)
|
||||
*
|
||||
* @param context DSpace Context
|
||||
* @param dso DSpace object
|
||||
* @param params Packager Parameters
|
||||
*/
|
||||
@Override
|
||||
public void finishObject(Context context, DSpaceObject dso, PackageParameters params)
|
||||
throws PackageValidationException, CrosswalkException,
|
||||
AuthorizeException, SQLException, IOException
|
||||
{
|
||||
if(dso.getType()==Constants.ITEM)
|
||||
{
|
||||
// Check if 'createMetadataFields' option is enabled (default=true)
|
||||
// This defaults to true as by default we should attempt to restore as much metadata as we can.
|
||||
// When 'createMetadataFields' is set to false, an ingest will fail if it attempts to ingest content to a missing metadata field.
|
||||
if (params.getBooleanProperty("createMetadataFields", true))
|
||||
{
|
||||
// We want to verify that all the Metadata Fields we've crosswalked
|
||||
// actually *exist* in the DB. If not, we'll try to create them
|
||||
createMissingMetadataFields(context, (Item) dso);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nothing extra to do to bitstream after ingestion.
|
||||
*/
|
||||
@Override
|
||||
public void finishBitstream(Context context,
|
||||
Bitstream bs,
|
||||
Element mfile,
|
||||
METSManifest manifest,
|
||||
PackageParameters params)
|
||||
throws MetadataValidationException, SQLException, AuthorizeException, IOException
|
||||
{
|
||||
// nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of DSpaceObject in this package; it is
|
||||
* in the TYPE attribute of the mets:mets element.
|
||||
*/
|
||||
@Override
|
||||
public int getObjectType(METSManifest manifest)
|
||||
throws PackageValidationException
|
||||
{
|
||||
Element mets = manifest.getMets();
|
||||
String typeStr = mets.getAttributeValue("TYPE");
|
||||
if (typeStr == null || typeStr.length() == 0)
|
||||
{
|
||||
throw new PackageValidationException("Manifest is missing the required mets@TYPE attribute.");
|
||||
}
|
||||
if (typeStr.startsWith("DSpace "))
|
||||
{
|
||||
typeStr = typeStr.substring(7);
|
||||
}
|
||||
int type = Constants.getTypeID(typeStr);
|
||||
if (type < 0)
|
||||
{
|
||||
throw new PackageValidationException("Manifest has unrecognized value in mets@TYPE attribute: " + typeStr);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name used to distinguish DSpace Configuration entries for this subclass.
|
||||
*/
|
||||
@Override
|
||||
public String getConfigurationName()
|
||||
{
|
||||
return "dspaceAIP";
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that all the unsaved, crosswalked metadata fields that have
|
||||
* been added to an Item actually exist in our Database. If they don't
|
||||
* exist, they are created within the proper database tables.
|
||||
* <P>
|
||||
* This method must be called *before* item.update(), as the call to update()
|
||||
* will throw a SQLException when attempting to save any fields which
|
||||
* don't already exist in the database.
|
||||
* <P>
|
||||
* NOTE: This will NOT create a missing Metadata Schema (e.g. "dc" schema),
|
||||
* as we do not have enough info to create schemas on the fly.
|
||||
*
|
||||
* @param context - DSpace Context
|
||||
* @param item - Item whose unsaved metadata fields we are testing
|
||||
* @throws AuthorizeException if a metadata field doesn't exist and current user is not authorized to create it (i.e. not an Admin)
|
||||
* @throws PackageValidationException if a metadata schema doesn't exist, as we cannot autocreate a schema
|
||||
*/
|
||||
protected static void createMissingMetadataFields(Context context, Item item)
|
||||
throws PackageValidationException, AuthorizeException, IOException, SQLException
|
||||
{
|
||||
// Get all metadata fields/values currently added to this Item
|
||||
DCValue allMD[] = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||
|
||||
// For each field, we'll check if it exists. If not, we'll create it.
|
||||
for(DCValue md : allMD)
|
||||
{
|
||||
MetadataSchema mdSchema = null;
|
||||
MetadataField mdField = null;
|
||||
try
|
||||
{
|
||||
//Try to access this Schema
|
||||
mdSchema = MetadataSchema.find(context, md.schema);
|
||||
//If Schema found, try to locate field from database
|
||||
if(mdSchema!=null)
|
||||
{
|
||||
mdField = MetadataField.findByElement(context, mdSchema.getSchemaID(), md.element, md.qualifier);
|
||||
}
|
||||
}
|
||||
catch(SQLException se)
|
||||
{
|
||||
//If a SQLException error is thrown, then this field does NOT exist in DB
|
||||
//Set field to null, so we know we need to create it
|
||||
mdField = null;
|
||||
}
|
||||
|
||||
// If our Schema was not found, we have a problem
|
||||
// We cannot easily create a Schema automatically -- as we don't know its Namespace
|
||||
if(mdSchema==null)
|
||||
{
|
||||
throw new PackageValidationException("Unknown Metadata Schema encountered (" + md.schema + ") when attempting to ingest an Item. You will need to create this Metadata Schema in DSpace Schema Registry before the Item can be ingested.");
|
||||
}
|
||||
|
||||
// If our Metadata Field is null, we will attempt to create it in the proper Schema
|
||||
if(mdField==null)
|
||||
{
|
||||
try
|
||||
{
|
||||
//initialize field (but don't set a scope note) & create it
|
||||
mdField = new MetadataField(mdSchema, md.element, md.qualifier, null);
|
||||
// NOTE: Only Adminstrators can create Metadata Fields -- create() will throw an AuthorizationException for non-Admins
|
||||
mdField.create(context);
|
||||
//log that field was created
|
||||
log.info("Located a missing metadata field (schema:'" + mdSchema.getName() +"', element:'"+ md.element +"', qualifier:'"+ md.qualifier +"') while ingesting Item. This missing field has been created in the DSpace Metadata Field Registry.");
|
||||
}
|
||||
catch(NonUniqueMetadataException ne)
|
||||
{ // This exception should never happen, as we already checked to make sure the field doesn't exist.
|
||||
// But, we'll catch it anyways so that the Java compiler doesn't get upset
|
||||
throw new SQLException("Unable to create Metadata Field (element='" + md.element + "', qualifier='" + md.qualifier + "') in Schema "+ mdSchema.getName() +".", ne);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a user help string which should describe the
|
||||
* additional valid command-line options that this packager
|
||||
* implementation will accept when using the <code>-o</code> or
|
||||
* <code>--option</code> flags with the Packager script.
|
||||
*
|
||||
* @return a string describing additional command-line options available
|
||||
* with this packager
|
||||
*/
|
||||
@Override
|
||||
public String getParameterHelp()
|
||||
{
|
||||
String parentHelp = super.getParameterHelp();
|
||||
|
||||
//Return superclass help info, plus the extra parameters/options that this class supports
|
||||
return parentHelp +
|
||||
"\n\n" +
|
||||
"* createMetadataFields=[boolean] " +
|
||||
"If true, ingest attempts to create any missing metadata fields." +
|
||||
"If false, ingest will fail if a metadata field is encountered which doesn't already exist. (default = true)" +
|
||||
"\n\n" +
|
||||
"* dmd=[dmdSecType] " +
|
||||
"Type of the METS <dmdSec> which should be used to restore item metadata (defaults to DIM, then MODS)";
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -345,7 +345,7 @@ public class PackageUtils
|
||||
* generic like ".xml", to accidentally get set to this format.
|
||||
* @param context - the context.
|
||||
* @param shortDesc - short descriptive name, used to locate existing format.
|
||||
* @param MIMEtype - mime content-type
|
||||
* @param MIMEType - mime content-type
|
||||
* @param desc - long description
|
||||
* @param internal value for the 'internal' flag of a new format if created.
|
||||
* @return BitstreamFormat object that was found or created. Never null.
|
||||
@@ -472,11 +472,10 @@ public class PackageUtils
|
||||
//(Note: Handle is not set until item is finished)
|
||||
WorkspaceItem wsi = WorkspaceItem.create(context, (Collection)parent, params.useCollectionTemplate());
|
||||
|
||||
// Finish creating item with specified handle
|
||||
// (this will either install item immediately or start a workflow, based on params)
|
||||
dso = finishCreateItem(context, wsi, handle, params);
|
||||
|
||||
return dso;
|
||||
// Please note that we are returning an Item which is *NOT* yet in the Archive,
|
||||
// and doesn't yet have a handle assigned.
|
||||
// This Item will remain "incomplete" until 'PackageUtils.finishCreateItem()' is called
|
||||
return wsi.getItem();
|
||||
|
||||
case Constants.SITE:
|
||||
return Site.find(context, Site.SITE_ID);
|
||||
@@ -528,7 +527,7 @@ public class PackageUtils
|
||||
// default: skip workflow, but otherwise normal submission (i.e. package treated like a SIP)
|
||||
else
|
||||
{
|
||||
// Intall item immediately with the specified handle
|
||||
// Install item immediately with the specified handle
|
||||
InstallItem.installItem(context, wsi, handle);
|
||||
|
||||
// return newly installed item
|
||||
@@ -802,7 +801,7 @@ public class PackageUtils
|
||||
* Also see the translateGroupNameForImport() method which does the opposite
|
||||
* of this method.
|
||||
*
|
||||
* @param relatedDso DSpaceObject associated with group
|
||||
* @param context current DSpace Context
|
||||
* @param groupName Group's name
|
||||
* @return the group name, with any internal IDs translated to Handles
|
||||
*/
|
||||
@@ -886,7 +885,7 @@ public class PackageUtils
|
||||
* Also see the translateGroupNameForExport() method which does the opposite
|
||||
* of this method.
|
||||
*
|
||||
* @param relatedDso DSpaceObject associated with group
|
||||
* @param context current DSpace Context
|
||||
* @param groupName Group's name
|
||||
* @return the group name, with any Handles translated to internal IDs
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@ import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.text.ParseException;
|
||||
|
||||
import com.coverity.security.Escape;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
@@ -280,21 +280,8 @@ public final class Utils
|
||||
*/
|
||||
public static String addEntities(String value)
|
||||
{
|
||||
if (value==null || value.length() == 0)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
value = value.replaceAll("&", "&");
|
||||
value = value.replaceAll("\"", """);
|
||||
|
||||
// actually, ' is an XML entity, not in HTML.
|
||||
// that's why it's commented out.
|
||||
// value = value.replaceAll("'", "'");
|
||||
value = value.replaceAll("<", "<");
|
||||
value = value.replaceAll(">", ">");
|
||||
|
||||
return value;
|
||||
return Escape.html(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,360 +1,360 @@
|
||||
/**
|
||||
* 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;
|
||||
// above package assignment temporary pending better aysnch release process
|
||||
// package org.dspace.ctask.integrity;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
|
||||
/** ClamScan.java
|
||||
*
|
||||
* A set of methods to scan using the
|
||||
* clamav daemon.
|
||||
*
|
||||
* TODO: add a check for the inputstream size limit
|
||||
*
|
||||
* @author wbossons
|
||||
*/
|
||||
|
||||
@Suspendable(invoked=Curator.Invoked.INTERACTIVE)
|
||||
public class ClamScan extends AbstractCurationTask
|
||||
{
|
||||
private static final int DEFAULT_CHUNK_SIZE = 4096;//2048
|
||||
private static final byte[] INSTREAM = "zINSTREAM\0".getBytes();
|
||||
private static final byte[] PING = "zPING\0".getBytes();
|
||||
private static final byte[] STATS = "nSTATS\n".getBytes();//prefix with z
|
||||
private static final byte[] IDSESSION = "zIDSESSION\0".getBytes();
|
||||
private static final byte[] END = "zEND\0".getBytes();
|
||||
private static final String PLUGIN_PREFIX = "clamav";
|
||||
private static final String INFECTED_MESSAGE = "had virus detected.";
|
||||
private static final String CLEAN_MESSAGE = "had no viruses detected.";
|
||||
private static final String CONNECT_FAIL_MESSAGE = "Unable to connect to virus service - check setup";
|
||||
private static final String SCAN_FAIL_MESSAGE = "Error encountered using virus service - check setup";
|
||||
private static final String NEW_ITEM_HANDLE = "in workflow";
|
||||
|
||||
private static Logger log = Logger.getLogger(ClamScan.class);
|
||||
|
||||
private static String host = null;
|
||||
private static int port = 0;
|
||||
private static int timeout = 0;
|
||||
private static boolean failfast = true;
|
||||
|
||||
private int status = Curator.CURATE_UNSET;
|
||||
private List<String> results = null;
|
||||
|
||||
private Socket socket = null;
|
||||
private DataOutputStream dataOutputStream = null;
|
||||
|
||||
@Override
|
||||
public void init(Curator curator, String taskId) throws IOException
|
||||
{
|
||||
super.init(curator, taskId);
|
||||
host = ConfigurationManager.getProperty(PLUGIN_PREFIX, "service.host");
|
||||
port = ConfigurationManager.getIntProperty(PLUGIN_PREFIX, "service.port");
|
||||
timeout = ConfigurationManager.getIntProperty(PLUGIN_PREFIX, "socket.timeout");
|
||||
failfast = ConfigurationManager.getBooleanProperty(PLUGIN_PREFIX, "scan.failfast");
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
/** openSession
|
||||
*
|
||||
* This method opens a session.
|
||||
*/
|
||||
|
||||
private void openSession() throws IOException
|
||||
{
|
||||
socket = new Socket();
|
||||
try
|
||||
{
|
||||
logDebugMessage("Connecting to " + host + ":" + port);
|
||||
socket.connect(new InetSocketAddress(host, port));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Failed to connect to clamd . . .", e);
|
||||
throw (e);
|
||||
}
|
||||
try
|
||||
{
|
||||
socket.setSoTimeout(timeout);
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
log.error("Could not set socket timeout . . . " + timeout + "ms", e);
|
||||
throw (new IOException(e));
|
||||
}
|
||||
try
|
||||
{
|
||||
dataOutputStream = new DataOutputStream(socket.getOutputStream());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Failed to open OutputStream . . . ", e);
|
||||
throw (e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dataOutputStream.write(IDSESSION);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Error initiating session with IDSESSION command . . . ", e);
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
|
||||
/** closeSession
|
||||
*
|
||||
* Close the IDSESSION in CLAMD
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void closeSession()
|
||||
{
|
||||
if (dataOutputStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataOutputStream.write(END);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Exception closing dataOutputStream", e);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
logDebugMessage("Closing the socket for ClamAv daemon . . . ");
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Exception closing socket", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** scan
|
||||
*
|
||||
* Issue the INSTREAM command and return the response to
|
||||
* and from the clamav daemon
|
||||
*
|
||||
* @param the bitstream for reporting results
|
||||
* @param the InputStream to read
|
||||
* @param the item handle for reporting results
|
||||
* @return a ScanResult representing the server response
|
||||
* @throws IOException
|
||||
*/
|
||||
final static byte[] buffer = new byte[DEFAULT_CHUNK_SIZE];;
|
||||
private int scan(Bitstream bitstream, InputStream inputstream, String itemHandle)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataOutputStream.write(INSTREAM);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Error writing INSTREAM command . . .");
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
int read = DEFAULT_CHUNK_SIZE;
|
||||
while (read == DEFAULT_CHUNK_SIZE)
|
||||
{
|
||||
try
|
||||
{
|
||||
read = inputstream.read(buffer);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Failed attempting to read the InputStream . . . ");
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
if (read == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
dataOutputStream.writeInt(read);
|
||||
dataOutputStream.write(buffer, 0, read);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Could not write to the socket . . . ");
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
dataOutputStream.writeInt(0);
|
||||
dataOutputStream.flush();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Error writing zero-length chunk to socket") ;
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
try
|
||||
{
|
||||
read = socket.getInputStream().read(buffer);
|
||||
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error( "Error reading result from socket");
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
|
||||
if (read > 0)
|
||||
{
|
||||
String response = new String(buffer, 0, read);
|
||||
logDebugMessage("Response: " + response);
|
||||
if (response.indexOf("FOUND") != -1)
|
||||
{
|
||||
String itemMsg = "item - " + itemHandle + ": ";
|
||||
String bsMsg = "bitstream - " + bitstream.getName() +
|
||||
": SequenceId - " + bitstream.getSequenceID() + ": infected";
|
||||
report(itemMsg + bsMsg);
|
||||
results.add(bsMsg);
|
||||
return Curator.CURATE_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Curator.CURATE_SUCCESS;
|
||||
}
|
||||
}
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
|
||||
private void formatResults(Item item) throws IOException
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Item: ").append(getItemHandle(item)).append(" ");
|
||||
if (status == Curator.CURATE_FAIL)
|
||||
{
|
||||
sb.append(INFECTED_MESSAGE);
|
||||
int count = 0;
|
||||
for (String scanresult : results)
|
||||
{
|
||||
sb.append("\n").append(scanresult).append("\n");
|
||||
count++;
|
||||
}
|
||||
sb.append(count).append(" virus(es) found. ")
|
||||
.append(" failfast: ").append(failfast);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append(CLEAN_MESSAGE);
|
||||
}
|
||||
setResult(sb.toString());
|
||||
}
|
||||
|
||||
private static String getItemHandle(Item item)
|
||||
{
|
||||
String handle = item.getHandle();
|
||||
return (handle != null) ? handle: NEW_ITEM_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
private void logDebugMessage(String message)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
// above package assignment temporary pending better aysnch release process
|
||||
// package org.dspace.ctask.integrity;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
|
||||
/** ClamScan.java
|
||||
*
|
||||
* A set of methods to scan using the
|
||||
* clamav daemon.
|
||||
*
|
||||
* TODO: add a check for the inputstream size limit
|
||||
*
|
||||
* @author wbossons
|
||||
*/
|
||||
|
||||
@Suspendable(invoked=Curator.Invoked.INTERACTIVE)
|
||||
public class ClamScan extends AbstractCurationTask
|
||||
{
|
||||
private static final int DEFAULT_CHUNK_SIZE = 4096;//2048
|
||||
private static final byte[] INSTREAM = "zINSTREAM\0".getBytes();
|
||||
private static final byte[] PING = "zPING\0".getBytes();
|
||||
private static final byte[] STATS = "nSTATS\n".getBytes();//prefix with z
|
||||
private static final byte[] IDSESSION = "zIDSESSION\0".getBytes();
|
||||
private static final byte[] END = "zEND\0".getBytes();
|
||||
private static final String PLUGIN_PREFIX = "clamav";
|
||||
private static final String INFECTED_MESSAGE = "had virus detected.";
|
||||
private static final String CLEAN_MESSAGE = "had no viruses detected.";
|
||||
private static final String CONNECT_FAIL_MESSAGE = "Unable to connect to virus service - check setup";
|
||||
private static final String SCAN_FAIL_MESSAGE = "Error encountered using virus service - check setup";
|
||||
private static final String NEW_ITEM_HANDLE = "in workflow";
|
||||
|
||||
private static Logger log = Logger.getLogger(ClamScan.class);
|
||||
|
||||
private static String host = null;
|
||||
private static int port = 0;
|
||||
private static int timeout = 0;
|
||||
private static boolean failfast = true;
|
||||
|
||||
private int status = Curator.CURATE_UNSET;
|
||||
private List<String> results = null;
|
||||
|
||||
private Socket socket = null;
|
||||
private DataOutputStream dataOutputStream = null;
|
||||
|
||||
@Override
|
||||
public void init(Curator curator, String taskId) throws IOException
|
||||
{
|
||||
super.init(curator, taskId);
|
||||
host = ConfigurationManager.getProperty(PLUGIN_PREFIX, "service.host");
|
||||
port = ConfigurationManager.getIntProperty(PLUGIN_PREFIX, "service.port");
|
||||
timeout = ConfigurationManager.getIntProperty(PLUGIN_PREFIX, "socket.timeout");
|
||||
failfast = ConfigurationManager.getBooleanProperty(PLUGIN_PREFIX, "scan.failfast");
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
/** openSession
|
||||
*
|
||||
* This method opens a session.
|
||||
*/
|
||||
|
||||
private void openSession() throws IOException
|
||||
{
|
||||
socket = new Socket();
|
||||
try
|
||||
{
|
||||
logDebugMessage("Connecting to " + host + ":" + port);
|
||||
socket.connect(new InetSocketAddress(host, port));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Failed to connect to clamd . . .", e);
|
||||
throw (e);
|
||||
}
|
||||
try
|
||||
{
|
||||
socket.setSoTimeout(timeout);
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
log.error("Could not set socket timeout . . . " + timeout + "ms", e);
|
||||
throw (new IOException(e));
|
||||
}
|
||||
try
|
||||
{
|
||||
dataOutputStream = new DataOutputStream(socket.getOutputStream());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Failed to open OutputStream . . . ", e);
|
||||
throw (e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
dataOutputStream.write(IDSESSION);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Error initiating session with IDSESSION command . . . ", e);
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
|
||||
/** closeSession
|
||||
*
|
||||
* Close the IDSESSION in CLAMD
|
||||
*
|
||||
*
|
||||
*/
|
||||
private void closeSession()
|
||||
{
|
||||
if (dataOutputStream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataOutputStream.write(END);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Exception closing dataOutputStream", e);
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
logDebugMessage("Closing the socket for ClamAv daemon . . . ");
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Exception closing socket", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** scan
|
||||
*
|
||||
* Issue the INSTREAM command and return the response to
|
||||
* and from the clamav daemon
|
||||
*
|
||||
* @param the bitstream for reporting results
|
||||
* @param the InputStream to read
|
||||
* @param the item handle for reporting results
|
||||
* @return a ScanResult representing the server response
|
||||
* @throws IOException
|
||||
*/
|
||||
final static byte[] buffer = new byte[DEFAULT_CHUNK_SIZE];;
|
||||
private int scan(Bitstream bitstream, InputStream inputstream, String itemHandle)
|
||||
{
|
||||
try
|
||||
{
|
||||
dataOutputStream.write(INSTREAM);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Error writing INSTREAM command . . .");
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
int read = DEFAULT_CHUNK_SIZE;
|
||||
while (read == DEFAULT_CHUNK_SIZE)
|
||||
{
|
||||
try
|
||||
{
|
||||
read = inputstream.read(buffer);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Failed attempting to read the InputStream . . . ");
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
if (read == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
dataOutputStream.writeInt(read);
|
||||
dataOutputStream.write(buffer, 0, read);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Could not write to the socket . . . ");
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
dataOutputStream.writeInt(0);
|
||||
dataOutputStream.flush();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("Error writing zero-length chunk to socket") ;
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
try
|
||||
{
|
||||
read = socket.getInputStream().read(buffer);
|
||||
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error( "Error reading result from socket");
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
|
||||
if (read > 0)
|
||||
{
|
||||
String response = new String(buffer, 0, read);
|
||||
logDebugMessage("Response: " + response);
|
||||
if (response.indexOf("FOUND") != -1)
|
||||
{
|
||||
String itemMsg = "item - " + itemHandle + ": ";
|
||||
String bsMsg = "bitstream - " + bitstream.getName() +
|
||||
": SequenceId - " + bitstream.getSequenceID() + ": infected";
|
||||
report(itemMsg + bsMsg);
|
||||
results.add(bsMsg);
|
||||
return Curator.CURATE_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Curator.CURATE_SUCCESS;
|
||||
}
|
||||
}
|
||||
return Curator.CURATE_ERROR;
|
||||
}
|
||||
|
||||
private void formatResults(Item item) throws IOException
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Item: ").append(getItemHandle(item)).append(" ");
|
||||
if (status == Curator.CURATE_FAIL)
|
||||
{
|
||||
sb.append(INFECTED_MESSAGE);
|
||||
int count = 0;
|
||||
for (String scanresult : results)
|
||||
{
|
||||
sb.append("\n").append(scanresult).append("\n");
|
||||
count++;
|
||||
}
|
||||
sb.append(count).append(" virus(es) found. ")
|
||||
.append(" failfast: ").append(failfast);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append(CLEAN_MESSAGE);
|
||||
}
|
||||
setResult(sb.toString());
|
||||
}
|
||||
|
||||
private static String getItemHandle(Item item)
|
||||
{
|
||||
String handle = item.getHandle();
|
||||
return (handle != null) ? handle: NEW_ITEM_HANDLE;
|
||||
}
|
||||
|
||||
|
||||
private void logDebugMessage(String message)
|
||||
{
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -351,7 +351,7 @@ public class EPerson extends DSpaceObject
|
||||
}
|
||||
|
||||
// Get all the epeople that match the query
|
||||
TableRowIterator rows = DatabaseManager.queryTable(context, "eperson",
|
||||
TableRowIterator rows = DatabaseManager.query(context,
|
||||
dbquery, paramArr);
|
||||
try
|
||||
{
|
||||
@@ -473,7 +473,7 @@ public class EPerson extends DSpaceObject
|
||||
|
||||
// NOTE: The use of 's' in the order by clause can not cause an SQL
|
||||
// injection because the string is derived from constant values above.
|
||||
TableRowIterator rows = DatabaseManager.queryTable(context, "eperson",
|
||||
TableRowIterator rows = DatabaseManager.query(context,
|
||||
"SELECT * FROM eperson ORDER BY "+s);
|
||||
|
||||
try
|
||||
@@ -955,7 +955,7 @@ public class EPerson extends DSpaceObject
|
||||
List<String> tableList = new ArrayList<String>();
|
||||
|
||||
// check for eperson in item table
|
||||
TableRowIterator tri = DatabaseManager.queryTable(myContext, "item",
|
||||
TableRowIterator tri = DatabaseManager.query(myContext,
|
||||
"SELECT * from item where submitter_id= ? ",
|
||||
getID());
|
||||
|
||||
@@ -976,7 +976,7 @@ public class EPerson extends DSpaceObject
|
||||
}
|
||||
|
||||
// check for eperson in workflowitem table
|
||||
tri = DatabaseManager.queryTable(myContext, "workflowitem",
|
||||
tri = DatabaseManager.query(myContext,
|
||||
"SELECT * from workflowitem where owner= ? ",
|
||||
getID());
|
||||
|
||||
@@ -997,7 +997,7 @@ public class EPerson extends DSpaceObject
|
||||
}
|
||||
|
||||
// check for eperson in tasklistitem table
|
||||
tri = DatabaseManager.queryTable(myContext, "tasklistitem",
|
||||
tri = DatabaseManager.query(myContext,
|
||||
"SELECT * from tasklistitem where eperson_id= ? ",
|
||||
getID());
|
||||
|
||||
|
@@ -1,421 +1,421 @@
|
||||
/**
|
||||
* 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.harvest;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
import org.dspace.storage.rdbms.TableRow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexey Maslov
|
||||
*/
|
||||
|
||||
public class HarvestedCollection
|
||||
{
|
||||
private Context context;
|
||||
private TableRow harvestRow;
|
||||
|
||||
public static final int TYPE_NONE = 0;
|
||||
public static final int TYPE_DMD = 1;
|
||||
public static final int TYPE_DMDREF = 2;
|
||||
public static final int TYPE_FULL = 3;
|
||||
|
||||
public static final int STATUS_READY = 0;
|
||||
public static final int STATUS_BUSY = 1;
|
||||
public static final int STATUS_QUEUED = 2;
|
||||
public static final int STATUS_OAI_ERROR = 3;
|
||||
public static final int STATUS_UNKNOWN_ERROR = -1;
|
||||
|
||||
/*
|
||||
* collection_id | integer | not null
|
||||
harvest_type | integer |
|
||||
oai_source | text |
|
||||
oai_set_id | text |
|
||||
harvest_message | text |
|
||||
metadata_config_id | text |
|
||||
harvest_status | integer |
|
||||
harvest_start_time | timestamp with time zone |
|
||||
*/
|
||||
|
||||
// TODO: make sure this guy knows to lock people out if the status is not zero.
|
||||
// i.e. someone editing a collection's setting from the admin menu should have
|
||||
// to stop an ongoing harvest before they can edit the settings.
|
||||
|
||||
|
||||
HarvestedCollection(Context c, TableRow row)
|
||||
{
|
||||
context = c;
|
||||
harvestRow = row;
|
||||
}
|
||||
|
||||
|
||||
public static void exists(Context c) throws SQLException {
|
||||
DatabaseManager.queryTable(c, "harvested_collection", "SELECT COUNT(*) FROM harvested_collection");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the harvest settings corresponding to this collection
|
||||
* @return a HarvestInstance object corresponding to this collection's settings, null if not found.
|
||||
*/
|
||||
public static HarvestedCollection find(Context c, int collectionId) throws SQLException
|
||||
{
|
||||
TableRow row = DatabaseManager.findByUnique(c, "harvested_collection", "collection_id", collectionId);
|
||||
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HarvestedCollection(c, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new harvest instance row for a specified collection.
|
||||
* @return a new HarvestInstance object
|
||||
*/
|
||||
public static HarvestedCollection create(Context c, int collectionId) throws SQLException {
|
||||
TableRow row = DatabaseManager.row("harvested_collection");
|
||||
row.setColumn("collection_id", collectionId);
|
||||
row.setColumn("harvest_type", 0);
|
||||
DatabaseManager.insert(c, row);
|
||||
|
||||
return new HarvestedCollection(c, row);
|
||||
}
|
||||
|
||||
/** Returns whether the specified collection is harvestable, i.e. whether its harvesting
|
||||
* options are set up correctly. This is distinct from "ready", since this collection may
|
||||
* be in process of being harvested.
|
||||
*/
|
||||
public static boolean isHarvestable(Context c, int collectionId) throws SQLException
|
||||
{
|
||||
HarvestedCollection hc = HarvestedCollection.find(c, collectionId);
|
||||
if (hc != null && hc.getHarvestType() > 0 && hc.getOaiSource() != null && hc.getOaiSetId() != null &&
|
||||
hc.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns whether this harvest instance is actually harvestable, i.e. whether its settings
|
||||
* options are set up correctly. This is distinct from "ready", since this collection may
|
||||
* be in process of being harvested.
|
||||
*/
|
||||
public boolean isHarvestable() throws SQLException
|
||||
{
|
||||
if (this.getHarvestType() > 0 && this.getOaiSource() != null && this.getOaiSetId() != null &&
|
||||
this.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns whether the specified collection is ready for immediate harvest.
|
||||
*/
|
||||
public static boolean isReady(Context c, int collectionId) throws SQLException
|
||||
{
|
||||
HarvestedCollection hc = HarvestedCollection.find(c, collectionId);
|
||||
return hc.isReady();
|
||||
}
|
||||
|
||||
public boolean isReady() throws SQLException
|
||||
{
|
||||
if (this.isHarvestable() && (this.getHarvestStatus() == HarvestedCollection.STATUS_READY || this.getHarvestStatus() == HarvestedCollection.STATUS_OAI_ERROR))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Find all collections that are set up for harvesting
|
||||
*
|
||||
* return: list of collection id's
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static List<Integer> findAll(Context c) throws SQLException
|
||||
{
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
"SELECT * FROM harvested_collection");
|
||||
|
||||
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||
while (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
collectionIds.add(row.getIntColumn("collection_id"));
|
||||
}
|
||||
|
||||
return collectionIds;
|
||||
}
|
||||
|
||||
/** Find all collections that are ready for harvesting
|
||||
*
|
||||
* return: list of collection id's
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static List<Integer> findReady(Context c) throws SQLException
|
||||
{
|
||||
int harvestInterval = ConfigurationManager.getIntProperty("harvester.harvestFrequency");
|
||||
if (harvestInterval == 0)
|
||||
{
|
||||
harvestInterval = 720;
|
||||
}
|
||||
|
||||
int expirationInterval = ConfigurationManager.getIntProperty("harvester.threadTimeout");
|
||||
if (expirationInterval == 0)
|
||||
{
|
||||
expirationInterval = 24;
|
||||
}
|
||||
|
||||
Date startTime;
|
||||
Date expirationTime;
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(new Date());
|
||||
calendar.add(Calendar.MINUTE, -1 * harvestInterval);
|
||||
startTime = calendar.getTime();
|
||||
|
||||
calendar.setTime(startTime);
|
||||
calendar.add(Calendar.HOUR, -2 * expirationInterval);
|
||||
expirationTime = calendar.getTime();
|
||||
|
||||
/* Select all collections whose last_harvest is before our start time, whose harvest_type *is not* 0 and whose status *is* 0 (available) or 3 (OAI Error). */
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
"SELECT * FROM harvested_collection WHERE (last_harvested < ? or last_harvested is null) and harvest_type > ? and (harvest_status = ? or harvest_status = ? or (harvest_status=? and harvest_start_time < ?)) ORDER BY last_harvested",
|
||||
new java.sql.Timestamp(startTime.getTime()), 0, HarvestedCollection.STATUS_READY, HarvestedCollection.STATUS_OAI_ERROR, HarvestedCollection.STATUS_BUSY, new java.sql.Timestamp(expirationTime.getTime()));
|
||||
|
||||
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||
|
||||
while (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
collectionIds.add(row.getIntColumn("collection_id"));
|
||||
}
|
||||
|
||||
return collectionIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all collections with the specified status flag
|
||||
* @param c
|
||||
* @param status see HarvestInstance.STATUS_...
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static List<Integer> findByStatus(Context c, int status) throws SQLException {
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
"SELECT * FROM harvested_collection WHERE harvest_status = ?", status);
|
||||
|
||||
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||
while (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
collectionIds.add(row.getIntColumn("collection_id"));
|
||||
}
|
||||
|
||||
return collectionIds;
|
||||
}
|
||||
|
||||
|
||||
/** Find the collection that was harvested the longest time ago.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Integer findOldestHarvest (Context c) throws SQLException {
|
||||
String query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? order by last_harvested asc limit 1";
|
||||
|
||||
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
|
||||
{
|
||||
query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? and rownum <= 1 order by last_harvested asc";
|
||||
}
|
||||
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
query, 0, 0);
|
||||
TableRow row = tri.next();
|
||||
|
||||
if (row != null)
|
||||
{
|
||||
return row.getIntColumn("collection_id");
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Find the collection that was harvested most recently.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Integer findNewestHarvest (Context c) throws SQLException {
|
||||
String query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? order by last_harvested desc limit 1";
|
||||
|
||||
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
|
||||
{
|
||||
query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? and rownum <= 1 order by last_harvested desc";
|
||||
}
|
||||
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
query , 0, 0);
|
||||
TableRow row = tri.next();
|
||||
|
||||
if (row != null)
|
||||
{
|
||||
return row.getIntColumn("collection_id");
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A function to set all harvesting-related parameters at once
|
||||
*/
|
||||
public void setHarvestParams(int type, String oaiSource, String oaiSetId, String mdConfigId) {
|
||||
setHarvestType(type);
|
||||
setOaiSource(oaiSource);
|
||||
setOaiSetId(oaiSetId);
|
||||
setHarvestMetadataConfig(mdConfigId);
|
||||
}
|
||||
|
||||
/* Setters for the appropriate harvesting-related columns */
|
||||
public void setHarvestType(int type) {
|
||||
harvestRow.setColumn("harvest_type",type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current status of the collection.
|
||||
*
|
||||
* @param status a HarvestInstance.STATUS_... constant
|
||||
*/
|
||||
public void setHarvestStatus(int status) {
|
||||
harvestRow.setColumn("harvest_status",status);
|
||||
}
|
||||
|
||||
public void setOaiSource(String oaiSource) {
|
||||
if (oaiSource == null || oaiSource.length() == 0) {
|
||||
harvestRow.setColumnNull("oai_source");
|
||||
}
|
||||
else {
|
||||
harvestRow.setColumn("oai_source",oaiSource);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOaiSetId(String oaiSetId) {
|
||||
if (oaiSetId == null || oaiSetId.length() == 0) {
|
||||
harvestRow.setColumnNull("oai_set_id");
|
||||
}
|
||||
else {
|
||||
harvestRow.setColumn("oai_set_id",oaiSetId);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHarvestMetadataConfig(String mdConfigId) {
|
||||
if (mdConfigId == null || mdConfigId.length() == 0) {
|
||||
harvestRow.setColumnNull("metadata_config_id");
|
||||
}
|
||||
else {
|
||||
harvestRow.setColumn("metadata_config_id",mdConfigId);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHarvestResult(Date date, String message) {
|
||||
if (date == null) {
|
||||
harvestRow.setColumnNull("last_harvested");
|
||||
} else {
|
||||
harvestRow.setColumn("last_harvested", date);
|
||||
}
|
||||
|
||||
if (message == null || message.length() == 0) {
|
||||
harvestRow.setColumnNull("harvest_message");
|
||||
} else {
|
||||
harvestRow.setColumn("harvest_message", message);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHarvestMessage(String message) {
|
||||
if (message == null || message.length() == 0) {
|
||||
harvestRow.setColumnNull("harvest_message");
|
||||
} else {
|
||||
harvestRow.setColumn("harvest_message", message);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHarvestStartTime(Date date) {
|
||||
if (date == null) {
|
||||
harvestRow.setColumnNull("harvest_start_time");
|
||||
} else {
|
||||
harvestRow.setColumn("harvest_start_time", date);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Getting for the appropriate harvesting-related columns */
|
||||
public int getCollectionId() {
|
||||
return harvestRow.getIntColumn("collection_id");
|
||||
}
|
||||
|
||||
public int getHarvestType() {
|
||||
return harvestRow.getIntColumn("harvest_type");
|
||||
}
|
||||
|
||||
public int getHarvestStatus() {
|
||||
return harvestRow.getIntColumn("harvest_status");
|
||||
}
|
||||
|
||||
public String getOaiSource() {
|
||||
return harvestRow.getStringColumn("oai_source");
|
||||
}
|
||||
|
||||
public String getOaiSetId() {
|
||||
return harvestRow.getStringColumn("oai_set_id");
|
||||
}
|
||||
|
||||
public String getHarvestMetadataConfig() {
|
||||
return harvestRow.getStringColumn("metadata_config_id");
|
||||
}
|
||||
|
||||
public String getHarvestMessage() {
|
||||
return harvestRow.getStringColumn("harvest_message");
|
||||
}
|
||||
|
||||
public Date getHarvestDate() {
|
||||
return harvestRow.getDateColumn("last_harvested");
|
||||
}
|
||||
|
||||
public Date getHarvestStartTime() {
|
||||
return harvestRow.getDateColumn("harvest_start_time");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void delete() throws SQLException {
|
||||
DatabaseManager.delete(context, harvestRow);
|
||||
}
|
||||
|
||||
public void update() throws SQLException, IOException, AuthorizeException
|
||||
{
|
||||
DatabaseManager.update(context, harvestRow);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* 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.harvest;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
import org.dspace.storage.rdbms.TableRow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Alexey Maslov
|
||||
*/
|
||||
|
||||
public class HarvestedCollection
|
||||
{
|
||||
private Context context;
|
||||
private TableRow harvestRow;
|
||||
|
||||
public static final int TYPE_NONE = 0;
|
||||
public static final int TYPE_DMD = 1;
|
||||
public static final int TYPE_DMDREF = 2;
|
||||
public static final int TYPE_FULL = 3;
|
||||
|
||||
public static final int STATUS_READY = 0;
|
||||
public static final int STATUS_BUSY = 1;
|
||||
public static final int STATUS_QUEUED = 2;
|
||||
public static final int STATUS_OAI_ERROR = 3;
|
||||
public static final int STATUS_UNKNOWN_ERROR = -1;
|
||||
|
||||
/*
|
||||
* collection_id | integer | not null
|
||||
harvest_type | integer |
|
||||
oai_source | text |
|
||||
oai_set_id | text |
|
||||
harvest_message | text |
|
||||
metadata_config_id | text |
|
||||
harvest_status | integer |
|
||||
harvest_start_time | timestamp with time zone |
|
||||
*/
|
||||
|
||||
// TODO: make sure this guy knows to lock people out if the status is not zero.
|
||||
// i.e. someone editing a collection's setting from the admin menu should have
|
||||
// to stop an ongoing harvest before they can edit the settings.
|
||||
|
||||
|
||||
HarvestedCollection(Context c, TableRow row)
|
||||
{
|
||||
context = c;
|
||||
harvestRow = row;
|
||||
}
|
||||
|
||||
|
||||
public static void exists(Context c) throws SQLException {
|
||||
DatabaseManager.queryTable(c, "harvested_collection", "SELECT COUNT(*) FROM harvested_collection");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the harvest settings corresponding to this collection
|
||||
* @return a HarvestInstance object corresponding to this collection's settings, null if not found.
|
||||
*/
|
||||
public static HarvestedCollection find(Context c, int collectionId) throws SQLException
|
||||
{
|
||||
TableRow row = DatabaseManager.findByUnique(c, "harvested_collection", "collection_id", collectionId);
|
||||
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HarvestedCollection(c, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new harvest instance row for a specified collection.
|
||||
* @return a new HarvestInstance object
|
||||
*/
|
||||
public static HarvestedCollection create(Context c, int collectionId) throws SQLException {
|
||||
TableRow row = DatabaseManager.row("harvested_collection");
|
||||
row.setColumn("collection_id", collectionId);
|
||||
row.setColumn("harvest_type", 0);
|
||||
DatabaseManager.insert(c, row);
|
||||
|
||||
return new HarvestedCollection(c, row);
|
||||
}
|
||||
|
||||
/** Returns whether the specified collection is harvestable, i.e. whether its harvesting
|
||||
* options are set up correctly. This is distinct from "ready", since this collection may
|
||||
* be in process of being harvested.
|
||||
*/
|
||||
public static boolean isHarvestable(Context c, int collectionId) throws SQLException
|
||||
{
|
||||
HarvestedCollection hc = HarvestedCollection.find(c, collectionId);
|
||||
if (hc != null && hc.getHarvestType() > 0 && hc.getOaiSource() != null && hc.getOaiSetId() != null &&
|
||||
hc.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns whether this harvest instance is actually harvestable, i.e. whether its settings
|
||||
* options are set up correctly. This is distinct from "ready", since this collection may
|
||||
* be in process of being harvested.
|
||||
*/
|
||||
public boolean isHarvestable() throws SQLException
|
||||
{
|
||||
if (this.getHarvestType() > 0 && this.getOaiSource() != null && this.getOaiSetId() != null &&
|
||||
this.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns whether the specified collection is ready for immediate harvest.
|
||||
*/
|
||||
public static boolean isReady(Context c, int collectionId) throws SQLException
|
||||
{
|
||||
HarvestedCollection hc = HarvestedCollection.find(c, collectionId);
|
||||
return hc.isReady();
|
||||
}
|
||||
|
||||
public boolean isReady() throws SQLException
|
||||
{
|
||||
if (this.isHarvestable() && (this.getHarvestStatus() == HarvestedCollection.STATUS_READY || this.getHarvestStatus() == HarvestedCollection.STATUS_OAI_ERROR))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Find all collections that are set up for harvesting
|
||||
*
|
||||
* return: list of collection id's
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static List<Integer> findAll(Context c) throws SQLException
|
||||
{
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
"SELECT * FROM harvested_collection");
|
||||
|
||||
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||
while (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
collectionIds.add(row.getIntColumn("collection_id"));
|
||||
}
|
||||
|
||||
return collectionIds;
|
||||
}
|
||||
|
||||
/** Find all collections that are ready for harvesting
|
||||
*
|
||||
* return: list of collection id's
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static List<Integer> findReady(Context c) throws SQLException
|
||||
{
|
||||
int harvestInterval = ConfigurationManager.getIntProperty("harvester.harvestFrequency");
|
||||
if (harvestInterval == 0)
|
||||
{
|
||||
harvestInterval = 720;
|
||||
}
|
||||
|
||||
int expirationInterval = ConfigurationManager.getIntProperty("harvester.threadTimeout");
|
||||
if (expirationInterval == 0)
|
||||
{
|
||||
expirationInterval = 24;
|
||||
}
|
||||
|
||||
Date startTime;
|
||||
Date expirationTime;
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(new Date());
|
||||
calendar.add(Calendar.MINUTE, -1 * harvestInterval);
|
||||
startTime = calendar.getTime();
|
||||
|
||||
calendar.setTime(startTime);
|
||||
calendar.add(Calendar.HOUR, -2 * expirationInterval);
|
||||
expirationTime = calendar.getTime();
|
||||
|
||||
/* Select all collections whose last_harvest is before our start time, whose harvest_type *is not* 0 and whose status *is* 0 (available) or 3 (OAI Error). */
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
"SELECT * FROM harvested_collection WHERE (last_harvested < ? or last_harvested is null) and harvest_type > ? and (harvest_status = ? or harvest_status = ? or (harvest_status=? and harvest_start_time < ?)) ORDER BY last_harvested",
|
||||
new java.sql.Timestamp(startTime.getTime()), 0, HarvestedCollection.STATUS_READY, HarvestedCollection.STATUS_OAI_ERROR, HarvestedCollection.STATUS_BUSY, new java.sql.Timestamp(expirationTime.getTime()));
|
||||
|
||||
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||
|
||||
while (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
collectionIds.add(row.getIntColumn("collection_id"));
|
||||
}
|
||||
|
||||
return collectionIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all collections with the specified status flag
|
||||
* @param c
|
||||
* @param status see HarvestInstance.STATUS_...
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static List<Integer> findByStatus(Context c, int status) throws SQLException {
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
"SELECT * FROM harvested_collection WHERE harvest_status = ?", status);
|
||||
|
||||
List<Integer> collectionIds = new ArrayList<Integer>();
|
||||
while (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
collectionIds.add(row.getIntColumn("collection_id"));
|
||||
}
|
||||
|
||||
return collectionIds;
|
||||
}
|
||||
|
||||
|
||||
/** Find the collection that was harvested the longest time ago.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Integer findOldestHarvest (Context c) throws SQLException {
|
||||
String query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? order by last_harvested asc limit 1";
|
||||
|
||||
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
|
||||
{
|
||||
query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? and rownum <= 1 order by last_harvested asc";
|
||||
}
|
||||
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
query, 0, 0);
|
||||
TableRow row = tri.next();
|
||||
|
||||
if (row != null)
|
||||
{
|
||||
return row.getIntColumn("collection_id");
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Find the collection that was harvested most recently.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Integer findNewestHarvest (Context c) throws SQLException {
|
||||
String query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? order by last_harvested desc limit 1";
|
||||
|
||||
if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
|
||||
{
|
||||
query = "select collection_id from harvested_collection where harvest_type > ? and harvest_status = ? and rownum <= 1 order by last_harvested desc";
|
||||
}
|
||||
|
||||
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
|
||||
query , 0, 0);
|
||||
TableRow row = tri.next();
|
||||
|
||||
if (row != null)
|
||||
{
|
||||
return row.getIntColumn("collection_id");
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A function to set all harvesting-related parameters at once
|
||||
*/
|
||||
public void setHarvestParams(int type, String oaiSource, String oaiSetId, String mdConfigId) {
|
||||
setHarvestType(type);
|
||||
setOaiSource(oaiSource);
|
||||
setOaiSetId(oaiSetId);
|
||||
setHarvestMetadataConfig(mdConfigId);
|
||||
}
|
||||
|
||||
/* Setters for the appropriate harvesting-related columns */
|
||||
public void setHarvestType(int type) {
|
||||
harvestRow.setColumn("harvest_type",type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current status of the collection.
|
||||
*
|
||||
* @param status a HarvestInstance.STATUS_... constant
|
||||
*/
|
||||
public void setHarvestStatus(int status) {
|
||||
harvestRow.setColumn("harvest_status",status);
|
||||
}
|
||||
|
||||
public void setOaiSource(String oaiSource) {
|
||||
if (oaiSource == null || oaiSource.length() == 0) {
|
||||
harvestRow.setColumnNull("oai_source");
|
||||
}
|
||||
else {
|
||||
harvestRow.setColumn("oai_source",oaiSource);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOaiSetId(String oaiSetId) {
|
||||
if (oaiSetId == null || oaiSetId.length() == 0) {
|
||||
harvestRow.setColumnNull("oai_set_id");
|
||||
}
|
||||
else {
|
||||
harvestRow.setColumn("oai_set_id",oaiSetId);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHarvestMetadataConfig(String mdConfigId) {
|
||||
if (mdConfigId == null || mdConfigId.length() == 0) {
|
||||
harvestRow.setColumnNull("metadata_config_id");
|
||||
}
|
||||
else {
|
||||
harvestRow.setColumn("metadata_config_id",mdConfigId);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHarvestResult(Date date, String message) {
|
||||
if (date == null) {
|
||||
harvestRow.setColumnNull("last_harvested");
|
||||
} else {
|
||||
harvestRow.setColumn("last_harvested", date);
|
||||
}
|
||||
|
||||
if (message == null || message.length() == 0) {
|
||||
harvestRow.setColumnNull("harvest_message");
|
||||
} else {
|
||||
harvestRow.setColumn("harvest_message", message);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHarvestMessage(String message) {
|
||||
if (message == null || message.length() == 0) {
|
||||
harvestRow.setColumnNull("harvest_message");
|
||||
} else {
|
||||
harvestRow.setColumn("harvest_message", message);
|
||||
}
|
||||
}
|
||||
|
||||
public void setHarvestStartTime(Date date) {
|
||||
if (date == null) {
|
||||
harvestRow.setColumnNull("harvest_start_time");
|
||||
} else {
|
||||
harvestRow.setColumn("harvest_start_time", date);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Getting for the appropriate harvesting-related columns */
|
||||
public int getCollectionId() {
|
||||
return harvestRow.getIntColumn("collection_id");
|
||||
}
|
||||
|
||||
public int getHarvestType() {
|
||||
return harvestRow.getIntColumn("harvest_type");
|
||||
}
|
||||
|
||||
public int getHarvestStatus() {
|
||||
return harvestRow.getIntColumn("harvest_status");
|
||||
}
|
||||
|
||||
public String getOaiSource() {
|
||||
return harvestRow.getStringColumn("oai_source");
|
||||
}
|
||||
|
||||
public String getOaiSetId() {
|
||||
return harvestRow.getStringColumn("oai_set_id");
|
||||
}
|
||||
|
||||
public String getHarvestMetadataConfig() {
|
||||
return harvestRow.getStringColumn("metadata_config_id");
|
||||
}
|
||||
|
||||
public String getHarvestMessage() {
|
||||
return harvestRow.getStringColumn("harvest_message");
|
||||
}
|
||||
|
||||
public Date getHarvestDate() {
|
||||
return harvestRow.getDateColumn("last_harvested");
|
||||
}
|
||||
|
||||
public Date getHarvestStartTime() {
|
||||
return harvestRow.getDateColumn("harvest_start_time");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void delete() throws SQLException {
|
||||
DatabaseManager.delete(context, harvestRow);
|
||||
}
|
||||
|
||||
public void update() throws SQLException, IOException, AuthorizeException
|
||||
{
|
||||
DatabaseManager.update(context, harvestRow);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,171 +1,171 @@
|
||||
/**
|
||||
* 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.harvest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRow;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
|
||||
/**
|
||||
* @author Alexey Maslov
|
||||
*/
|
||||
|
||||
public class HarvestedItem
|
||||
{
|
||||
private Context context;
|
||||
private TableRow harvestRow;
|
||||
|
||||
|
||||
HarvestedItem(Context c, TableRow row)
|
||||
{
|
||||
context = c;
|
||||
harvestRow = row;
|
||||
}
|
||||
|
||||
|
||||
public static void exists(Context c) throws SQLException {
|
||||
DatabaseManager.queryTable(c, "harvested_item", "SELECT COUNT(*) FROM harvested_item");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the harvest parameters corresponding to the specified DSpace item
|
||||
* @return a HarvestedItem object corresponding to this item, null if not found.
|
||||
*/
|
||||
public static HarvestedItem find(Context c, int item_id) throws SQLException
|
||||
{
|
||||
TableRow row = DatabaseManager.findByUnique(c, "harvested_item", "item_id", item_id);
|
||||
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HarvestedItem(c, row);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* select foo.item_id from (select item.item_id, item.owning_collection from item join item2bundle on item.item_id=item2bundle.item_id where item2bundle.bundle_id=22) as foo join collection on foo.owning_collection=collection.collection_id where collection.collection_id=5;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve a DSpace Item that corresponds to this particular combination of owning collection and OAI ID.
|
||||
* @param context
|
||||
* @param itemOaiID the string used by the OAI-PMH provider to identify the item
|
||||
* @param collectionID id of the local collection that the item should be found in
|
||||
* @return DSpace Item or null if no item was found
|
||||
*/
|
||||
public static Item getItemByOAIId(Context context, String itemOaiID, int collectionID) throws SQLException
|
||||
{
|
||||
/*
|
||||
* FYI: This method has to be scoped to a collection. Otherwise, we could have collisions as more
|
||||
* than one collection might be importing the same item. That is OAI_ID's might be unique to the
|
||||
* provider but not to the harvester.
|
||||
*/
|
||||
Item resolvedItem = null;
|
||||
TableRowIterator tri = null;
|
||||
final String selectItemFromOaiId = "SELECT dsi.item_id FROM " +
|
||||
"(SELECT item.item_id, item.owning_collection FROM item JOIN harvested_item ON item.item_id=harvested_item.item_id WHERE harvested_item.oai_id=?) " +
|
||||
"dsi JOIN collection ON dsi.owning_collection=collection.collection_id WHERE collection.collection_id=?";
|
||||
|
||||
try
|
||||
{
|
||||
tri = DatabaseManager.query(context, selectItemFromOaiId, itemOaiID, collectionID);
|
||||
|
||||
if (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
int itemID = row.getIntColumn("item_id");
|
||||
resolvedItem = Item.find(context, itemID);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (tri != null)
|
||||
{
|
||||
tri.close();
|
||||
}
|
||||
}
|
||||
|
||||
return resolvedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new harvested item row for a specified item id.
|
||||
* @return a new HarvestedItem object
|
||||
*/
|
||||
public static HarvestedItem create(Context c, int itemId, String itemOAIid) throws SQLException {
|
||||
TableRow row = DatabaseManager.row("harvested_item");
|
||||
row.setColumn("item_id", itemId);
|
||||
row.setColumn("oai_id", itemOAIid);
|
||||
DatabaseManager.insert(c, row);
|
||||
|
||||
return new HarvestedItem(c, row);
|
||||
}
|
||||
|
||||
|
||||
public String getItemID()
|
||||
{
|
||||
String oai_id = harvestRow.getStringColumn("item_id");
|
||||
|
||||
return oai_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the oai_id associated with this item
|
||||
*/
|
||||
public String getOaiID()
|
||||
{
|
||||
String oai_id = harvestRow.getStringColumn("oai_id");
|
||||
|
||||
return oai_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the oai_id associated with this item
|
||||
*/
|
||||
public void setOaiID(String itemOaiID)
|
||||
{
|
||||
harvestRow.setColumn("oai_id",itemOaiID);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public void setHarvestDate(Date date) {
|
||||
if (date == null) {
|
||||
date = new Date();
|
||||
}
|
||||
harvestRow.setColumn("last_harvested", date);
|
||||
}
|
||||
|
||||
public Date getHarvestDate() {
|
||||
return harvestRow.getDateColumn("last_harvested");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void delete() throws SQLException {
|
||||
DatabaseManager.delete(context, harvestRow);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void update() throws SQLException, IOException, AuthorizeException {
|
||||
DatabaseManager.update(context, harvestRow);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 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.harvest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRow;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
|
||||
/**
|
||||
* @author Alexey Maslov
|
||||
*/
|
||||
|
||||
public class HarvestedItem
|
||||
{
|
||||
private Context context;
|
||||
private TableRow harvestRow;
|
||||
|
||||
|
||||
HarvestedItem(Context c, TableRow row)
|
||||
{
|
||||
context = c;
|
||||
harvestRow = row;
|
||||
}
|
||||
|
||||
|
||||
public static void exists(Context c) throws SQLException {
|
||||
DatabaseManager.queryTable(c, "harvested_item", "SELECT COUNT(*) FROM harvested_item");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the harvest parameters corresponding to the specified DSpace item
|
||||
* @return a HarvestedItem object corresponding to this item, null if not found.
|
||||
*/
|
||||
public static HarvestedItem find(Context c, int item_id) throws SQLException
|
||||
{
|
||||
TableRow row = DatabaseManager.findByUnique(c, "harvested_item", "item_id", item_id);
|
||||
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HarvestedItem(c, row);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* select foo.item_id from (select item.item_id, item.owning_collection from item join item2bundle on item.item_id=item2bundle.item_id where item2bundle.bundle_id=22) as foo join collection on foo.owning_collection=collection.collection_id where collection.collection_id=5;
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve a DSpace Item that corresponds to this particular combination of owning collection and OAI ID.
|
||||
* @param context
|
||||
* @param itemOaiID the string used by the OAI-PMH provider to identify the item
|
||||
* @param collectionID id of the local collection that the item should be found in
|
||||
* @return DSpace Item or null if no item was found
|
||||
*/
|
||||
public static Item getItemByOAIId(Context context, String itemOaiID, int collectionID) throws SQLException
|
||||
{
|
||||
/*
|
||||
* FYI: This method has to be scoped to a collection. Otherwise, we could have collisions as more
|
||||
* than one collection might be importing the same item. That is OAI_ID's might be unique to the
|
||||
* provider but not to the harvester.
|
||||
*/
|
||||
Item resolvedItem = null;
|
||||
TableRowIterator tri = null;
|
||||
final String selectItemFromOaiId = "SELECT dsi.item_id FROM " +
|
||||
"(SELECT item.item_id, item.owning_collection FROM item JOIN harvested_item ON item.item_id=harvested_item.item_id WHERE harvested_item.oai_id=?) " +
|
||||
"dsi JOIN collection ON dsi.owning_collection=collection.collection_id WHERE collection.collection_id=?";
|
||||
|
||||
try
|
||||
{
|
||||
tri = DatabaseManager.query(context, selectItemFromOaiId, itemOaiID, collectionID);
|
||||
|
||||
if (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
int itemID = row.getIntColumn("item_id");
|
||||
resolvedItem = Item.find(context, itemID);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (tri != null)
|
||||
{
|
||||
tri.close();
|
||||
}
|
||||
}
|
||||
|
||||
return resolvedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new harvested item row for a specified item id.
|
||||
* @return a new HarvestedItem object
|
||||
*/
|
||||
public static HarvestedItem create(Context c, int itemId, String itemOAIid) throws SQLException {
|
||||
TableRow row = DatabaseManager.row("harvested_item");
|
||||
row.setColumn("item_id", itemId);
|
||||
row.setColumn("oai_id", itemOAIid);
|
||||
DatabaseManager.insert(c, row);
|
||||
|
||||
return new HarvestedItem(c, row);
|
||||
}
|
||||
|
||||
|
||||
public String getItemID()
|
||||
{
|
||||
String oai_id = harvestRow.getStringColumn("item_id");
|
||||
|
||||
return oai_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the oai_id associated with this item
|
||||
*/
|
||||
public String getOaiID()
|
||||
{
|
||||
String oai_id = harvestRow.getStringColumn("oai_id");
|
||||
|
||||
return oai_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the oai_id associated with this item
|
||||
*/
|
||||
public void setOaiID(String itemOaiID)
|
||||
{
|
||||
harvestRow.setColumn("oai_id",itemOaiID);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public void setHarvestDate(Date date) {
|
||||
if (date == null) {
|
||||
date = new Date();
|
||||
}
|
||||
harvestRow.setColumn("last_harvested", date);
|
||||
}
|
||||
|
||||
public Date getHarvestDate() {
|
||||
return harvestRow.getDateColumn("last_harvested");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void delete() throws SQLException {
|
||||
DatabaseManager.delete(context, harvestRow);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void update() throws SQLException, IOException, AuthorizeException {
|
||||
DatabaseManager.update(context, harvestRow);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1102,6 +1102,7 @@ public class DatabaseManager
|
||||
break;
|
||||
|
||||
case Types.INTEGER:
|
||||
case Types.NUMERIC:
|
||||
if (isOracle)
|
||||
{
|
||||
long longValue = results.getLong(i);
|
||||
@@ -1120,7 +1121,6 @@ public class DatabaseManager
|
||||
}
|
||||
break;
|
||||
|
||||
case Types.NUMERIC:
|
||||
case Types.DECIMAL:
|
||||
case Types.BIGINT:
|
||||
row.setColumn(name, results.getLong(i));
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#
|
||||
# http://www.dspace.org/license/
|
||||
#
|
||||
|
||||
browse.page-title = Browsing DSpace
|
||||
browse.et-al = et al
|
||||
|
||||
@@ -480,6 +481,8 @@ jsp.error.404.title = Error: Documen
|
||||
jsp.error.authorize.text1 = You do not have permission to perform the action you just attempted.
|
||||
jsp.error.authorize.text2 = If you think you should have authorization, please feel free to contact the DSpace administrators:
|
||||
jsp.error.authorize.title = Authorization Required
|
||||
jsp.error.exceeded-size.text1 = Sorry, but the file you have tried to upload ({0} bytes) exceeds the maximum file size limit of ({1} bytes). You can contact the repository manager with questions about this limit.
|
||||
jsp.error.exceeded-size.title = Exceeded Maximum File Size Error
|
||||
jsp.error.integrity.heading = System Error: Malformed Request
|
||||
jsp.error.integrity.list1 = Sometimes, if you used your browser's "back" button during an operation like a submission, clicking on a button may try and do something that's already been done, such as commit the submission to the archive. Clicking your browsers "reload" or "refresh" button may have similar results.
|
||||
jsp.error.integrity.list2 = If you got here by following a link or bookmark provided by someone else, the link may be incorrect or you mistyped the link. Please check the link and try again.
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -314,6 +314,23 @@ public class ItemTest extends AbstractDSpaceObjectTest
|
||||
assertTrue("testGetMetadata_String 5",dc.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* A test for DS-806: Item.match() incorrect logic for schema testing
|
||||
*/
|
||||
@Test
|
||||
public void testDS806()
|
||||
{
|
||||
// Set the item to have two pieces of metadata for dc.type and dc2.type
|
||||
String dcType = "DC-TYPE";
|
||||
String testType = "TEST-TYPE";
|
||||
it.addMetadata("dc", "type", null, null, dcType);
|
||||
it.addMetadata("test", "type", null, null, testType);
|
||||
|
||||
// Check that only one is returned when we ask for all dc.type values
|
||||
DCValue[] values = it.getMetadata("dc", "type", null, null);
|
||||
assertTrue("Return results", values.length == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of addDC method, of class Item.
|
||||
*/
|
||||
|
@@ -1784,7 +1784,7 @@ crosswalk.submission.SWORD.stylesheet = crosswalks/sword-swap-ingest.xsl
|
||||
# which DSpace will construct the deposit location urls for
|
||||
# collections.
|
||||
#
|
||||
# The default is {dspace.url}/sword/deposit
|
||||
# The default is {dspace.baseUrl}/sword/deposit
|
||||
#
|
||||
# In the event that you are not deploying DSpace as the ROOT
|
||||
# application in the servlet container, this will generate
|
||||
@@ -1797,7 +1797,7 @@ crosswalk.submission.SWORD.stylesheet = crosswalks/sword-swap-ingest.xsl
|
||||
# URL from which DSpace will construct the service document
|
||||
# location urls for the site, and for individual collections
|
||||
#
|
||||
# The default is {dspace.url}/sword/servicedocument
|
||||
# The default is {dspace.baseUrl}/sword/servicedocument
|
||||
#
|
||||
# In the event that you are not deploying DSpace as the ROOT
|
||||
# application in the servlet container, this will generate
|
||||
@@ -1810,7 +1810,7 @@ crosswalk.submission.SWORD.stylesheet = crosswalks/sword-swap-ingest.xsl
|
||||
# which DSpace will use to construct the media link urls
|
||||
# for items which are deposited via sword
|
||||
#
|
||||
# The default is {dspace.url}/sword/media-link
|
||||
# The default is {dspace.baseUrl}/sword/media-link
|
||||
#
|
||||
# In the event that you are not deploying DSpace as the ROOT
|
||||
# application in the servlet container, this will generate
|
||||
|
@@ -584,4 +584,18 @@
|
||||
<scope_note>Nature or genre of content.</scope_note>
|
||||
</dc-type>
|
||||
|
||||
|
||||
<!-- A second test schema for testing purposes. -->
|
||||
<dc-schema>
|
||||
<name>test</name>
|
||||
<namespace>http://example.com/test/</namespace>
|
||||
</dc-schema>
|
||||
|
||||
<dc-type>
|
||||
<schema>test</schema>
|
||||
<element>type</element>
|
||||
<!-- unqualified -->
|
||||
<scope_note>A second test schema type element.</scope_note>
|
||||
</dc-type>
|
||||
|
||||
</dspace-dc-types>
|
||||
|
@@ -1,124 +1,118 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-provider</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<name>DSpace Discovery :: Discovery Provider Library</name>
|
||||
<description>
|
||||
|
||||
|
||||
|
||||
Build Information
|
||||
$Id: pom.xml 5367 2010-09-30 00:30:11Z mdiggory $
|
||||
$URL: https://scm.dspace.org/svn/repo/modules/dspace-discovery/trunk/provider/pom.xml $
|
||||
</description>
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>discovery-modules</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.cocoon</groupId>
|
||||
<artifactId>cocoon-maven-plugin</artifactId>
|
||||
<version>1.0.0-M2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>prepare</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>6.1.7</version>
|
||||
<configuration>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8888</port>
|
||||
<maxIdleTime>30000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
|
||||
<contextPath>/</contextPath>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>org.apache.cocoon.mode</name>
|
||||
<value>dev</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<Cocoon-Block-Name>${pom.artifactId}</Cocoon-Block-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update
|
||||
against when changes have occured, this spawns a new build cycle
|
||||
and releases snapshots into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-provider</connection>
|
||||
<developerConnection>
|
||||
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-provider
|
||||
</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-provider</url>
|
||||
</scm>
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-provider</artifactId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<name>DSpace Discovery :: Discovery Provider Library</name>
|
||||
<description>
|
||||
|
||||
|
||||
|
||||
Build Information
|
||||
$Id: pom.xml 5367 2010-09-30 00:30:11Z mdiggory $
|
||||
$URL: https://scm.dspace.org/svn/repo/modules/dspace-discovery/trunk/provider/pom.xml $
|
||||
</description>
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>discovery-modules</artifactId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/../..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.cocoon</groupId>
|
||||
<artifactId>cocoon-maven-plugin</artifactId>
|
||||
<version>1.0.0-M2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>prepare</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>6.1.7</version>
|
||||
<configuration>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8888</port>
|
||||
<maxIdleTime>30000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
|
||||
<contextPath>/</contextPath>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>org.apache.cocoon.mode</name>
|
||||
<value>dev</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<Cocoon-Block-Name>${pom.artifactId}</Cocoon-Block-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
@@ -44,6 +44,8 @@ public class SearchUtils {
|
||||
|
||||
private static List<String> dateIndexableFields = new ArrayList<String>();
|
||||
|
||||
public static final String FILTER_SEPARATOR = "|||";
|
||||
|
||||
static {
|
||||
|
||||
log.debug("loading configuration");
|
||||
@@ -190,6 +192,20 @@ public class SearchUtils {
|
||||
return dateIndexableFields;
|
||||
}
|
||||
|
||||
public static String getFilterQueryDisplay(String filterQuery){
|
||||
String separator = SearchUtils.getConfig().getString("solr.facets.split.char", SearchUtils.FILTER_SEPARATOR);
|
||||
//Escape any regex chars
|
||||
separator = java.util.regex.Pattern.quote(separator);
|
||||
String[] fqParts = filterQuery.split(separator);
|
||||
String result = "";
|
||||
int start = fqParts.length / 2;
|
||||
for(int i = start; i < fqParts.length; i++){
|
||||
result += fqParts[i];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class SolrFacetConfig {
|
||||
|
||||
private String facetField;
|
||||
|
@@ -8,6 +8,7 @@
|
||||
package org.dspace.discovery;
|
||||
|
||||
import org.apache.commons.collections.ExtendedProperties;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang.time.DateFormatUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
@@ -699,7 +700,10 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
|
||||
if(SearchUtils.getAllFacets().contains(field) || SearchUtils.getAllFacets().contains(unqualifiedField + "." + Item.ANY)){
|
||||
//Add a special filter
|
||||
doc.addField(field + "_filter", value);
|
||||
//We use a separator to split up the lowercase and regular case, this is needed to get our filters in regular case
|
||||
//Solr has issues with facet prefix and cases
|
||||
String separator = SearchUtils.getConfig().getString("solr.facets.split.char", SearchUtils.FILTER_SEPARATOR);
|
||||
doc.addField(field + "_filter", value.toLowerCase() + separator + value);
|
||||
}
|
||||
|
||||
if(SearchUtils.getSortFields().contains(field) && !sortFieldsAdded.contains(field)){
|
||||
@@ -773,9 +777,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
||||
readers.add(is);
|
||||
|
||||
// Add each InputStream to the Indexed Document
|
||||
// (Acts like an Append)
|
||||
// doc.addField("default", is);
|
||||
//doc.add(new Field("default", is));
|
||||
doc.addField("fulltext", IOUtils.toString(is));
|
||||
|
||||
log.debug(" Added BitStream: "
|
||||
+ myBitstreams[j].getStoreNumber() + " "
|
||||
|
@@ -1,130 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-xmlui-api</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<name>DSpace Discovery :: Discovery XMLUI API</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>discovery-modules</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-xmlui-api</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- external -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-provider</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.cocoon</groupId>
|
||||
<artifactId>cocoon-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>prepare</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<attachClasses>true</attachClasses>
|
||||
<classesClassifier>classes</classesClassifier>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>6.1.7</version>
|
||||
<configuration>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8888</port>
|
||||
<maxIdleTime>30000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
|
||||
<contextPath>/</contextPath>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>org.apache.cocoon.mode</name>
|
||||
<value>dev</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<index>true</index>
|
||||
<manifestEntries>
|
||||
<Cocoon-Block-Name>discovery-xmlui-block</Cocoon-Block-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
-->
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update
|
||||
against when changes have occured, this spawns a new build cycle
|
||||
and releases snapshots into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-api</connection>
|
||||
<developerConnection>
|
||||
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-api
|
||||
</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-api</url>
|
||||
</scm>
|
||||
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-xmlui-api</artifactId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<name>DSpace Discovery :: Discovery XMLUI API</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>discovery-modules</artifactId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/../..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-xmlui-api</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- external -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-provider</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.cocoon</groupId>
|
||||
<artifactId>cocoon-maven-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>prepare</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<attachClasses>true</attachClasses>
|
||||
<classesClassifier>classes</classesClassifier>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>6.1.7</version>
|
||||
<configuration>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8888</port>
|
||||
<maxIdleTime>30000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
|
||||
<contextPath>/</contextPath>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>org.apache.cocoon.mode</name>
|
||||
<value>dev</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<index>true</index>
|
||||
<manifestEntries>
|
||||
<Cocoon-Block-Name>discovery-xmlui-block</Cocoon-Block-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
-->
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
@@ -37,7 +37,6 @@ import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.URLEncoder;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -386,7 +385,7 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
||||
continue;
|
||||
}
|
||||
for (FacetField.Count count : facetVals) {
|
||||
values.add(new FilterDisplayValue(count.getName(), count.getCount(), count.getAsFilterQuery()));
|
||||
values.add(new FilterDisplayValue(SearchUtils.getFilterQueryDisplay(count.getName()), count.getCount(), count.getAsFilterQuery()));
|
||||
}
|
||||
}
|
||||
if(field.isDate()){
|
||||
@@ -463,9 +462,12 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
||||
if(keys != null){
|
||||
while (keys.hasMoreElements()){
|
||||
String key = (String) keys.nextElement();
|
||||
if(key != null){
|
||||
paramsQuery += key + "=" + URLEncoder.encode(request.getParameter(key), "UTF-8");
|
||||
paramsQuery += "&";
|
||||
if(key != null && !"page".equals(key)){
|
||||
String[] vals = request.getParameterValues(key);
|
||||
for(String paramValue : vals){
|
||||
paramsQuery += key + "=" + paramValue;
|
||||
paramsQuery += "&";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -476,7 +478,7 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
|
||||
"/discover?" +
|
||||
paramsQuery +
|
||||
"fq=" +
|
||||
URLEncoder.encode(filterQuery, "UTF-8"),
|
||||
filterQuery,
|
||||
displayedValue + " (" + value.getCount() + ")"
|
||||
);
|
||||
}
|
||||
|
@@ -120,6 +120,13 @@ public class Navigation extends AbstractDSpaceTransformer implements CacheablePr
|
||||
browseGlobal.addItem().addXref(contextPath + "/community-list", T_head_all_of_dspace );
|
||||
*/
|
||||
|
||||
/* regulate the ordering */
|
||||
options.addList("discovery");
|
||||
options.addList("browse");
|
||||
options.addList("account");
|
||||
options.addList("context");
|
||||
options.addList("administrative");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -132,9 +132,9 @@ public class RelatedItems extends AbstractFiltersTransformer
|
||||
|
||||
this.queryArgs = prepareDefaultFilters(getView());
|
||||
this.queryArgs.setRows(1);
|
||||
this.queryArgs.add("fl","author,handle");
|
||||
this.queryArgs.add("fl","dc.contributor,dc.contributor.author,handle");
|
||||
this.queryArgs.add("mlt","true");
|
||||
this.queryArgs.add("mlt.fl","author,handle");
|
||||
this.queryArgs.add("mlt.fl","dc.contributor,dc.contributor.author,handle");
|
||||
this.queryArgs.add("mlt.mindf","1");
|
||||
this.queryArgs.add("mlt.mintf","1");
|
||||
this.queryArgs.setQuery("handle:" + dso.getHandle());
|
||||
|
@@ -558,7 +558,7 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
||||
|
||||
//No use in selecting the same filter twice
|
||||
if(filterQueries.contains(filterQuery)){
|
||||
cell.addContent(displayedValue + " (" + value.getCount() + ")");
|
||||
cell.addContent(SearchUtils.getFilterQueryDisplay(displayedValue) + " (" + value.getCount() + ")");
|
||||
} else {
|
||||
//Add the basics
|
||||
Map<String, String> urlParams = new HashMap<String, String>();
|
||||
@@ -567,8 +567,8 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
|
||||
//Add already existing filter queries
|
||||
url = addFilterQueriesToUrl(url);
|
||||
//Last add the current filter query
|
||||
url += "&fq=" + URLEncoder.encode(filterQuery, "UTF-8");
|
||||
cell.addXref(url, displayedValue + " (" + value.getCount() + ")"
|
||||
url += "&fq=" + filterQuery;
|
||||
cell.addXref(url, SearchUtils.getFilterQueryDisplay(displayedValue) + " (" + value.getCount() + ")"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -97,7 +97,7 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
||||
// String searchUrl = SearchUtils.getConfig().getString("solr.search.server");
|
||||
// if(searchUrl != null && !searchUrl.endsWith("/"))
|
||||
// searchUrl += "/";
|
||||
String searchUrl = ConfigurationManager.getProperty("dspace.url") + "/JSON/discovery/searchSolr";
|
||||
String searchUrl = contextPath + "/JSON/discovery/searchSolr";
|
||||
|
||||
search.addHidden("solr-search-url").setValue(searchUrl);
|
||||
search.addHidden("contextpath").setValue(contextPath);
|
||||
@@ -166,6 +166,9 @@ public class SimpleSearch extends AbstractSearch implements CacheableProcessingC
|
||||
if(field.equals("location.comm") || field.equals("location.coll")){
|
||||
//We have a community/collection, resolve it to a dspaceObject
|
||||
value = SolrServiceImpl.locationToName(context, field, value);
|
||||
} else
|
||||
if(field.endsWith("_filter")){
|
||||
value = SearchUtils.getFilterQueryDisplay(value);
|
||||
}
|
||||
//Check for a range query
|
||||
Pattern pattern = Pattern.compile("\\[(.*? TO .*?)\\]");
|
||||
|
@@ -1,155 +1,164 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to you under the Apache License, Version
|
||||
2.0 (the "License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 Unless required by
|
||||
applicable law or agreed to in writing, software distributed under the
|
||||
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the License for
|
||||
the specific language governing permissions and limitations under the
|
||||
License.
|
||||
-->
|
||||
<!-- $Id: pom.xml 4739 2010-02-04 16:53:55Z benbosman $ -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>war</packaging>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-xmlui-webapp</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<name>DSpace Discovery :: Discovery XMLUI Webapp</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>discovery-modules</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-xmlui-api</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-xmlui-api</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- external -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.cocoon</groupId>
|
||||
<artifactId>cocoon-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>prepare</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<attachClasses>true</attachClasses>
|
||||
<classesClassifier>classes</classesClassifier>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/webapp</directory>
|
||||
<includes>
|
||||
<include>WEB-INF/web.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>6.1.7</version>
|
||||
<configuration>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8888</port>
|
||||
<maxIdleTime>30000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
|
||||
<contextPath>/</contextPath>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>org.apache.cocoon.mode</name>
|
||||
<value>dev</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<index>true</index>
|
||||
<manifestEntries>
|
||||
<Cocoon-Block-Name>discovery-xmlui-block</Cocoon-Block-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
-->
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update
|
||||
against when changes have occured, this spawns a new build cycle
|
||||
and releases snapshots into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-webapp</connection>
|
||||
<developerConnection>
|
||||
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-webapp
|
||||
</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-webapp</url>
|
||||
</scm>
|
||||
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to you under the Apache License, Version
|
||||
2.0 (the "License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 Unless required by
|
||||
applicable law or agreed to in writing, software distributed under the
|
||||
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the License for
|
||||
the specific language governing permissions and limitations under the
|
||||
License.
|
||||
-->
|
||||
<!-- $Id: pom.xml 4739 2010-02-04 16:53:55Z benbosman $ -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>war</packaging>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-xmlui-webapp</artifactId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<name>DSpace Discovery :: Discovery XMLUI Webapp</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>discovery-modules</artifactId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/../..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-xmlui-api</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-discovery-xmlui-api</artifactId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- external -->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.cocoon</groupId>
|
||||
<artifactId>cocoon-maven-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>prepare</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>prepare</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<attachClasses>true</attachClasses>
|
||||
<classesClassifier>classes</classesClassifier>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/webapp</directory>
|
||||
<includes>
|
||||
<include>WEB-INF/web.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>6.1.7</version>
|
||||
<configuration>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8888</port>
|
||||
<maxIdleTime>30000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
|
||||
<contextPath>/</contextPath>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>org.apache.cocoon.mode</name>
|
||||
<value>dev</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--Exclude license check for Discovery files which don't need it-->
|
||||
<excludes>
|
||||
<exclude>**/COPYRIGHT.txt</exclude>
|
||||
<exclude>**/LICENSE.txt</exclude>
|
||||
<exclude>**/*.LICENSE</exclude>
|
||||
<exclude>**/jquery*</exclude>
|
||||
<exclude>**/jquery/*</exclude>
|
||||
<exclude>**/*.xmap</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<index>true</index>
|
||||
<manifestEntries>
|
||||
<Cocoon-Block-Name>discovery-xmlui-block</Cocoon-Block-Name>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
-->
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
@@ -1,67 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>discovery-modules</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<name>DSpace Discovery :: Modules</name>
|
||||
|
||||
<parent>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<groupId>org.dspace</groupId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>dspace-discovery-provider</module>
|
||||
<module>dspace-discovery-xmlui-api</module>
|
||||
<module>dspace-discovery-xmlui-webapp</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>6.1.7</version>
|
||||
<configuration>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8888</port>
|
||||
<maxIdleTime>30000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
|
||||
<contextPath>/</contextPath>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>org.apache.cocoon.mode</name>
|
||||
<value>dev</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update
|
||||
against when changes have occured, this spawns a new build cycle
|
||||
and releases snapshots into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery</connection>
|
||||
<developerConnection>
|
||||
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery
|
||||
</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery</url>
|
||||
</scm>
|
||||
|
||||
<issueManagement>
|
||||
<system>JIRA</system>
|
||||
<url>http://jira.dspace.org/jira/browse/DISCOVERY</url>
|
||||
</issueManagement>
|
||||
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>pom</packaging>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>discovery-modules</artifactId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<name>DSpace Discovery :: Modules</name>
|
||||
|
||||
<parent>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<groupId>org.dspace</groupId>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>dspace-discovery-provider</module>
|
||||
<module>dspace-discovery-xmlui-api</module>
|
||||
<module>dspace-discovery-xmlui-webapp</module>
|
||||
</modules>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>maven-jetty-plugin</artifactId>
|
||||
<version>6.1.7</version>
|
||||
<configuration>
|
||||
<connectors>
|
||||
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
|
||||
<port>8888</port>
|
||||
<maxIdleTime>30000</maxIdleTime>
|
||||
</connector>
|
||||
</connectors>
|
||||
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
|
||||
<contextPath>/</contextPath>
|
||||
<systemProperties>
|
||||
<systemProperty>
|
||||
<name>org.apache.cocoon.mode</name>
|
||||
<value>dev</value>
|
||||
</systemProperty>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<issueManagement>
|
||||
<system>JIRA</system>
|
||||
<url>http://jira.dspace.org/jira/browse/DISCOVERY</url>
|
||||
</issueManagement>
|
||||
|
||||
</project>
|
||||
|
@@ -14,19 +14,14 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-jspui</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update against
|
||||
when changes have occured, this spawns a new build cycle and releases snapshots
|
||||
into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui/dspace-jspui-api</connection>
|
||||
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui/dspace-jspui-api</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui/dspace-jspui-api</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/../..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -80,4 +75,4 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@@ -98,7 +98,7 @@ public class BrowserServlet extends AbstractBrowserServlet
|
||||
throws ServletException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
JSPManager.showJSP(request, response, "/browse/error.jsp");
|
||||
JSPManager.showInternalError(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -19,6 +19,7 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.dspace.app.util.SubmissionInfo;
|
||||
@@ -219,7 +220,14 @@ public class SubmissionController extends DSpaceServlet
|
||||
if ((contentType != null)
|
||||
&& (contentType.indexOf("multipart/form-data") != -1))
|
||||
{
|
||||
request = wrapMultipartRequest(request);
|
||||
try
|
||||
{
|
||||
request = wrapMultipartRequest(request);
|
||||
} catch (FileSizeLimitExceededException e)
|
||||
{
|
||||
log.warn("Upload exceeded upload.max");
|
||||
JSPManager.showFileSizeLimitExceededError(request, response, e.getMessage(), e.getActualSize(), e.getPermittedSize());
|
||||
}
|
||||
|
||||
//also, upload any files and save their contents to Request (for later processing by UploadStep)
|
||||
uploadFiles(context, request);
|
||||
@@ -1350,7 +1358,7 @@ public class SubmissionController extends DSpaceServlet
|
||||
* if there are no more pages in this step
|
||||
*/
|
||||
private HttpServletRequest wrapMultipartRequest(HttpServletRequest request)
|
||||
throws ServletException
|
||||
throws ServletException, FileSizeLimitExceededException
|
||||
{
|
||||
HttpServletRequest wrappedRequest;
|
||||
|
||||
@@ -1370,6 +1378,10 @@ public class SubmissionController extends DSpaceServlet
|
||||
return request;
|
||||
}
|
||||
}
|
||||
catch (FileSizeLimitExceededException e)
|
||||
{
|
||||
throw new FileSizeLimitExceededException(e.getMessage(),e.getActualSize(),e.getPermittedSize());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ServletException(e);
|
||||
|
@@ -18,6 +18,7 @@ import java.util.List;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
@@ -457,88 +458,83 @@ public class CollectionWizardServlet extends DSpaceServlet
|
||||
HttpServletResponse response) throws SQLException,
|
||||
ServletException, IOException, AuthorizeException
|
||||
{
|
||||
// Wrap multipart request to get the submission info
|
||||
FileUploadRequest wrapper = new FileUploadRequest(request);
|
||||
|
||||
Collection collection = Collection.find(context, UIUtil
|
||||
.getIntParameter(wrapper, "collection_id"));
|
||||
|
||||
if (collection == null)
|
||||
{
|
||||
log.warn(LogManager.getHeader(context, "integrity_error", UIUtil
|
||||
.getRequestLogInfo(wrapper)));
|
||||
JSPManager.showIntegrityError(request, response);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get metadata
|
||||
collection.setMetadata("name", wrapper.getParameter("name"));
|
||||
collection.setMetadata("short_description", wrapper
|
||||
.getParameter("short_description"));
|
||||
collection.setMetadata("introductory_text", wrapper
|
||||
.getParameter("introductory_text"));
|
||||
collection.setMetadata("copyright_text", wrapper
|
||||
.getParameter("copyright_text"));
|
||||
collection.setMetadata("side_bar_text", wrapper
|
||||
.getParameter("side_bar_text"));
|
||||
collection.setMetadata("provenance_description", wrapper
|
||||
.getParameter("provenance_description"));
|
||||
|
||||
// Need to be more careful about license -- make sure it's null if
|
||||
// nothing was entered
|
||||
String license = wrapper.getParameter("license");
|
||||
|
||||
if (!StringUtils.isEmpty(license))
|
||||
{
|
||||
collection.setLicense(license);
|
||||
}
|
||||
|
||||
File temp = wrapper.getFile("file");
|
||||
|
||||
if (temp != null)
|
||||
{
|
||||
// Read the temp file as logo
|
||||
InputStream is = new BufferedInputStream(new FileInputStream(temp));
|
||||
Bitstream logoBS = collection.setLogo(is);
|
||||
|
||||
// Strip all but the last filename. It would be nice
|
||||
// to know which OS the file came from.
|
||||
String noPath = wrapper.getFilesystemName("file");
|
||||
|
||||
while (noPath.indexOf('/') > -1)
|
||||
try {
|
||||
// Wrap multipart request to get the submission info
|
||||
FileUploadRequest wrapper = new FileUploadRequest(request);
|
||||
Collection collection = Collection.find(context, UIUtil.getIntParameter(wrapper, "collection_id"));
|
||||
if (collection == null)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('/') + 1);
|
||||
log.warn(LogManager.getHeader(context, "integrity_error", UIUtil.getRequestLogInfo(wrapper)));
|
||||
JSPManager.showIntegrityError(request, response);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (noPath.indexOf('\\') > -1)
|
||||
// Get metadata
|
||||
collection.setMetadata("name", wrapper.getParameter("name"));
|
||||
collection.setMetadata("short_description", wrapper.getParameter("short_description"));
|
||||
collection.setMetadata("introductory_text", wrapper.getParameter("introductory_text"));
|
||||
collection.setMetadata("copyright_text", wrapper.getParameter("copyright_text"));
|
||||
collection.setMetadata("side_bar_text", wrapper.getParameter("side_bar_text"));
|
||||
collection.setMetadata("provenance_description", wrapper.getParameter("provenance_description"));
|
||||
// Need to be more careful about license -- make sure it's null if
|
||||
// nothing was entered
|
||||
String license = wrapper.getParameter("license");
|
||||
|
||||
if (!StringUtils.isEmpty(license))
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('\\') + 1);
|
||||
collection.setLicense(license);
|
||||
}
|
||||
|
||||
logoBS.setName(noPath);
|
||||
logoBS.setSource(wrapper.getFilesystemName("file"));
|
||||
File temp = wrapper.getFile("file");
|
||||
|
||||
// Identify the format
|
||||
BitstreamFormat bf = FormatIdentifier.guessFormat(context, logoBS);
|
||||
logoBS.setFormat(bf);
|
||||
AuthorizeManager.addPolicy(context, logoBS, Constants.WRITE, context
|
||||
.getCurrentUser());
|
||||
logoBS.update();
|
||||
|
||||
// Remove temp file
|
||||
if (!temp.delete())
|
||||
if (temp != null)
|
||||
{
|
||||
log.trace("Unable to delete temporary file");
|
||||
// Read the temp file as logo
|
||||
InputStream is = new BufferedInputStream(new FileInputStream(temp));
|
||||
Bitstream logoBS = collection.setLogo(is);
|
||||
|
||||
// Strip all but the last filename. It would be nice
|
||||
// to know which OS the file came from.
|
||||
String noPath = wrapper.getFilesystemName("file");
|
||||
|
||||
while (noPath.indexOf('/') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('/') + 1);
|
||||
}
|
||||
|
||||
while (noPath.indexOf('\\') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('\\') + 1);
|
||||
}
|
||||
|
||||
logoBS.setName(noPath);
|
||||
logoBS.setSource(wrapper.getFilesystemName("file"));
|
||||
|
||||
// Identify the format
|
||||
BitstreamFormat bf = FormatIdentifier.guessFormat(context, logoBS);
|
||||
logoBS.setFormat(bf);
|
||||
AuthorizeManager.addPolicy(context, logoBS, Constants.WRITE, context.getCurrentUser());
|
||||
logoBS.update();
|
||||
|
||||
// Remove temp file
|
||||
if (!temp.delete())
|
||||
{
|
||||
log.trace("Unable to delete temporary file");
|
||||
}
|
||||
}
|
||||
|
||||
collection.update();
|
||||
|
||||
// Now work out what next page is
|
||||
showNextPage(context, request, response, collection, BASIC_INFO);
|
||||
|
||||
context.complete();
|
||||
} catch (FileSizeLimitExceededException ex)
|
||||
{
|
||||
log.warn("Upload exceeded upload.max");
|
||||
JSPManager.showFileSizeLimitExceededError(request, response, ex.getMessage(), ex.getActualSize(), ex.getPermittedSize());
|
||||
}
|
||||
|
||||
collection.update();
|
||||
|
||||
// Now work out what next page is
|
||||
showNextPage(context, request, response, collection, BASIC_INFO);
|
||||
|
||||
context.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -17,6 +17,7 @@ import java.sql.SQLException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.app.util.AuthorizeUtil;
|
||||
@@ -893,92 +894,93 @@ public class EditCommunitiesServlet extends DSpaceServlet
|
||||
HttpServletResponse response) throws ServletException, IOException,
|
||||
SQLException, AuthorizeException
|
||||
{
|
||||
// Wrap multipart request to get the submission info
|
||||
FileUploadRequest wrapper = new FileUploadRequest(request);
|
||||
try {
|
||||
// Wrap multipart request to get the submission info
|
||||
FileUploadRequest wrapper = new FileUploadRequest(request);
|
||||
Community community = Community.find(context, UIUtil.getIntParameter(wrapper, "community_id"));
|
||||
Collection collection = Collection.find(context, UIUtil.getIntParameter(wrapper, "collection_id"));
|
||||
File temp = wrapper.getFile("file");
|
||||
|
||||
Community community = Community.find(context, UIUtil.getIntParameter(
|
||||
wrapper, "community_id"));
|
||||
Collection collection = Collection.find(context, UIUtil
|
||||
.getIntParameter(wrapper, "collection_id"));
|
||||
// Read the temp file as logo
|
||||
InputStream is = new BufferedInputStream(new FileInputStream(temp));
|
||||
Bitstream logoBS;
|
||||
|
||||
File temp = wrapper.getFile("file");
|
||||
if (collection == null)
|
||||
{
|
||||
logoBS = community.setLogo(is);
|
||||
}
|
||||
else
|
||||
{
|
||||
logoBS = collection.setLogo(is);
|
||||
}
|
||||
|
||||
// Read the temp file as logo
|
||||
InputStream is = new BufferedInputStream(new FileInputStream(temp));
|
||||
Bitstream logoBS;
|
||||
// Strip all but the last filename. It would be nice
|
||||
// to know which OS the file came from.
|
||||
String noPath = wrapper.getFilesystemName("file");
|
||||
|
||||
if (collection == null)
|
||||
while (noPath.indexOf('/') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('/') + 1);
|
||||
}
|
||||
|
||||
while (noPath.indexOf('\\') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('\\') + 1);
|
||||
}
|
||||
|
||||
logoBS.setName(noPath);
|
||||
logoBS.setSource(wrapper.getFilesystemName("file"));
|
||||
|
||||
// Identify the format
|
||||
BitstreamFormat bf = FormatIdentifier.guessFormat(context, logoBS);
|
||||
logoBS.setFormat(bf);
|
||||
AuthorizeManager.addPolicy(context, logoBS, Constants.WRITE, context.getCurrentUser());
|
||||
logoBS.update();
|
||||
|
||||
String jsp;
|
||||
DSpaceObject dso;
|
||||
if (collection == null)
|
||||
{
|
||||
community.update();
|
||||
|
||||
// Show community edit page
|
||||
request.setAttribute("community", community);
|
||||
storeAuthorizeAttributeCommunityEdit(context, request, community);
|
||||
dso = community;
|
||||
jsp = "/tools/edit-community.jsp";
|
||||
}
|
||||
else
|
||||
{
|
||||
collection.update();
|
||||
|
||||
// Show collection edit page
|
||||
request.setAttribute("collection", collection);
|
||||
request.setAttribute("community", community);
|
||||
storeAuthorizeAttributeCollectionEdit(context, request, collection);
|
||||
dso = collection;
|
||||
jsp = "/tools/edit-collection.jsp";
|
||||
}
|
||||
|
||||
if (AuthorizeManager.isAdmin(context, dso))
|
||||
{
|
||||
// set a variable to show all buttons
|
||||
request.setAttribute("admin_button", Boolean.TRUE);
|
||||
}
|
||||
|
||||
JSPManager.showJSP(request, response, jsp);
|
||||
|
||||
// Remove temp file
|
||||
if (!temp.delete())
|
||||
{
|
||||
log.error("Unable to delete temporary file");
|
||||
}
|
||||
|
||||
// Update DB
|
||||
context.complete();
|
||||
} catch (FileSizeLimitExceededException ex)
|
||||
{
|
||||
logoBS = community.setLogo(is);
|
||||
log.warn("Upload exceeded upload.max");
|
||||
JSPManager.showFileSizeLimitExceededError(request, response, ex.getMessage(), ex.getActualSize(), ex.getPermittedSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
logoBS = collection.setLogo(is);
|
||||
}
|
||||
|
||||
// Strip all but the last filename. It would be nice
|
||||
// to know which OS the file came from.
|
||||
String noPath = wrapper.getFilesystemName("file");
|
||||
|
||||
while (noPath.indexOf('/') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('/') + 1);
|
||||
}
|
||||
|
||||
while (noPath.indexOf('\\') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('\\') + 1);
|
||||
}
|
||||
|
||||
logoBS.setName(noPath);
|
||||
logoBS.setSource(wrapper.getFilesystemName("file"));
|
||||
|
||||
// Identify the format
|
||||
BitstreamFormat bf = FormatIdentifier.guessFormat(context, logoBS);
|
||||
logoBS.setFormat(bf);
|
||||
AuthorizeManager.addPolicy(context, logoBS, Constants.WRITE, context
|
||||
.getCurrentUser());
|
||||
logoBS.update();
|
||||
|
||||
String jsp;
|
||||
DSpaceObject dso;
|
||||
if (collection == null)
|
||||
{
|
||||
community.update();
|
||||
|
||||
// Show community edit page
|
||||
request.setAttribute("community", community);
|
||||
storeAuthorizeAttributeCommunityEdit(context, request, community);
|
||||
dso = community;
|
||||
jsp = "/tools/edit-community.jsp";
|
||||
}
|
||||
else
|
||||
{
|
||||
collection.update();
|
||||
|
||||
// Show collection edit page
|
||||
request.setAttribute("collection", collection);
|
||||
request.setAttribute("community", community);
|
||||
storeAuthorizeAttributeCollectionEdit(context, request, collection);
|
||||
dso = collection;
|
||||
jsp = "/tools/edit-collection.jsp";
|
||||
}
|
||||
|
||||
if (AuthorizeManager.isAdmin(context, dso))
|
||||
{
|
||||
// set a variable to show all buttons
|
||||
request.setAttribute("admin_button", Boolean.TRUE);
|
||||
}
|
||||
|
||||
JSPManager.showJSP(request, response, jsp);
|
||||
|
||||
// Remove temp file
|
||||
if (!temp.delete())
|
||||
{
|
||||
log.error("Unable to delete temporary file");
|
||||
}
|
||||
|
||||
// Update DB
|
||||
context.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import java.util.StringTokenizer;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.app.util.AuthorizeUtil;
|
||||
@@ -766,77 +767,80 @@ public class EditItemServlet extends DSpaceServlet
|
||||
throws ServletException, IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
// Wrap multipart request to get the submission info
|
||||
FileUploadRequest wrapper = new FileUploadRequest(request);
|
||||
Bitstream b = null;
|
||||
try {
|
||||
// Wrap multipart request to get the submission info
|
||||
FileUploadRequest wrapper = new FileUploadRequest(request);
|
||||
Bitstream b = null;
|
||||
Item item = Item.find(context, UIUtil.getIntParameter(wrapper, "item_id"));
|
||||
File temp = wrapper.getFile("file");
|
||||
|
||||
Item item = Item.find(context, UIUtil.getIntParameter(wrapper,
|
||||
"item_id"));
|
||||
// Read the temp file as logo
|
||||
InputStream is = new BufferedInputStream(new FileInputStream(temp));
|
||||
|
||||
File temp = wrapper.getFile("file");
|
||||
// now check to see if person can edit item
|
||||
checkEditAuthorization(context, item);
|
||||
|
||||
// Read the temp file as logo
|
||||
InputStream is = new BufferedInputStream(new FileInputStream(temp));
|
||||
// do we already have an ORIGINAL bundle?
|
||||
Bundle[] bundles = item.getBundles("ORIGINAL");
|
||||
|
||||
// now check to see if person can edit item
|
||||
checkEditAuthorization(context, item);
|
||||
|
||||
// do we already have an ORIGINAL bundle?
|
||||
Bundle[] bundles = item.getBundles("ORIGINAL");
|
||||
|
||||
if (bundles.length < 1)
|
||||
{
|
||||
// set bundle's name to ORIGINAL
|
||||
b = item.createSingleBitstream(is, "ORIGINAL");
|
||||
|
||||
// set the permission as defined in the owning collection
|
||||
Collection owningCollection = item.getOwningCollection();
|
||||
if (owningCollection != null)
|
||||
if (bundles.length < 1)
|
||||
{
|
||||
Bundle bnd = b.getBundles()[0];
|
||||
bnd.inheritCollectionDefaultPolicies(owningCollection);
|
||||
// set bundle's name to ORIGINAL
|
||||
b = item.createSingleBitstream(is, "ORIGINAL");
|
||||
|
||||
// set the permission as defined in the owning collection
|
||||
Collection owningCollection = item.getOwningCollection();
|
||||
if (owningCollection != null)
|
||||
{
|
||||
Bundle bnd = b.getBundles()[0];
|
||||
bnd.inheritCollectionDefaultPolicies(owningCollection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have a bundle already, just add bitstream
|
||||
b = bundles[0].createBitstream(is);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// Strip all but the last filename. It would be nice
|
||||
// to know which OS the file came from.
|
||||
String noPath = wrapper.getFilesystemName("file");
|
||||
|
||||
while (noPath.indexOf('/') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('/') + 1);
|
||||
}
|
||||
|
||||
while (noPath.indexOf('\\') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('\\') + 1);
|
||||
}
|
||||
|
||||
b.setName(noPath);
|
||||
b.setSource(wrapper.getFilesystemName("file"));
|
||||
|
||||
// Identify the format
|
||||
BitstreamFormat bf = FormatIdentifier.guessFormat(context, b);
|
||||
b.setFormat(bf);
|
||||
b.update();
|
||||
|
||||
item.update();
|
||||
|
||||
// Back to edit form
|
||||
showEditForm(context, request, response, item);
|
||||
|
||||
// Remove temp file
|
||||
if (!temp.delete())
|
||||
{
|
||||
log.error("Unable to delete temporary file");
|
||||
}
|
||||
|
||||
// Update DB
|
||||
context.complete();
|
||||
} catch (FileSizeLimitExceededException ex)
|
||||
{
|
||||
// we have a bundle already, just add bitstream
|
||||
b = bundles[0].createBitstream(is);
|
||||
log.warn("Upload exceeded upload.max");
|
||||
JSPManager.showFileSizeLimitExceededError(request, response, ex.getMessage(), ex.getActualSize(), ex.getPermittedSize());
|
||||
}
|
||||
|
||||
// Strip all but the last filename. It would be nice
|
||||
// to know which OS the file came from.
|
||||
String noPath = wrapper.getFilesystemName("file");
|
||||
|
||||
while (noPath.indexOf('/') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('/') + 1);
|
||||
}
|
||||
|
||||
while (noPath.indexOf('\\') > -1)
|
||||
{
|
||||
noPath = noPath.substring(noPath.indexOf('\\') + 1);
|
||||
}
|
||||
|
||||
b.setName(noPath);
|
||||
b.setSource(wrapper.getFilesystemName("file"));
|
||||
|
||||
// Identify the format
|
||||
BitstreamFormat bf = FormatIdentifier.guessFormat(context, b);
|
||||
b.setFormat(bf);
|
||||
b.update();
|
||||
|
||||
item.update();
|
||||
|
||||
// Back to edit form
|
||||
showEditForm(context, request, response, item);
|
||||
|
||||
// Remove temp file
|
||||
if (!temp.delete())
|
||||
{
|
||||
log.error("Unable to delete temporary file");
|
||||
}
|
||||
|
||||
// Update DB
|
||||
context.complete();
|
||||
}
|
||||
}
|
||||
|
@@ -87,7 +87,7 @@ public class WithdrawnBrowserServlet extends AbstractBrowserServlet
|
||||
{
|
||||
request.setAttribute("useAdminLayout", "yes");
|
||||
|
||||
JSPManager.showJSP(request, response, "/browse/error.jsp");
|
||||
JSPManager.showInternalError(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
@@ -47,7 +48,7 @@ public class FileUploadRequest extends HttpServletRequestWrapper
|
||||
* @param req
|
||||
* the original request
|
||||
*/
|
||||
public FileUploadRequest(HttpServletRequest req) throws IOException
|
||||
public FileUploadRequest(HttpServletRequest req) throws IOException, FileSizeLimitExceededException
|
||||
{
|
||||
super(req);
|
||||
|
||||
@@ -90,6 +91,16 @@ public class FileUploadRequest extends HttpServletRequestWrapper
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if(e.getMessage().contains("exceeds the configured maximum"))
|
||||
{
|
||||
// ServletFileUpload is not throwing the correct error, so this is workaround
|
||||
// the request was rejected because its size (11302) exceeds the configured maximum (536)
|
||||
int startFirstParen = e.getMessage().indexOf("(")+1;
|
||||
int endFirstParen = e.getMessage().indexOf(")");
|
||||
String uploadedSize = e.getMessage().substring(startFirstParen, endFirstParen).trim();
|
||||
Long actualSize = Long.parseLong(uploadedSize);
|
||||
throw new FileSizeLimitExceededException(e.getMessage(), actualSize, maxSize);
|
||||
}
|
||||
throw new IOException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
@@ -183,4 +194,4 @@ public class FileUploadRequest extends HttpServletRequestWrapper
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -142,4 +142,26 @@ public class JSPManager
|
||||
|
||||
showJSP(request, response, "/error/invalid-id.jsp");
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a "file upload was too large" error message. Passing in information
|
||||
* about the size of the file uploaded, and the maximum file size limit so
|
||||
* the user knows why they encountered an error.
|
||||
* @param request
|
||||
* @param response
|
||||
* @param message
|
||||
* @param actualSize
|
||||
* @param permittedSize
|
||||
* @throws ServletException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void showFileSizeLimitExceededError(HttpServletRequest request,
|
||||
HttpServletResponse response, String message, long actualSize, long permittedSize) throws ServletException, IOException
|
||||
{
|
||||
request.setAttribute("error.message", message);
|
||||
request.setAttribute("actualSize", actualSize);
|
||||
request.setAttribute("permittedSize", permittedSize);
|
||||
response.setStatus(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
|
||||
showJSP(request, response, "/error/exceeded-size.jsp");
|
||||
}
|
||||
}
|
||||
|
@@ -14,19 +14,14 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-jspui</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update against
|
||||
when changes have occured, this spawns a new build cycle and releases snapshots
|
||||
into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui/dspace-jspui-webapp</connection>
|
||||
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui/dspace-jspui-webapp</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui/dspace-jspui-webapp</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/../..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
@@ -53,6 +48,18 @@
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--Exclude license check for JSPUI files which don't need it-->
|
||||
<excludes>
|
||||
<exclude>**/robots.txt</exclude>
|
||||
<exclude>**/readme*</exclude>
|
||||
<exclude>**/*.tld</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
@@ -27,6 +27,7 @@
|
||||
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
|
||||
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%
|
||||
EPerson[] epeople =
|
||||
@@ -115,10 +116,10 @@
|
||||
<%= (e.getEmail() == null ? "" : e.getEmail()) %>
|
||||
</td>
|
||||
<td headers="t3" class="<%= row %>RowOddCol">
|
||||
<%= (e.getLastName() == null ? "" : e.getLastName()) %>
|
||||
<%= (e.getLastName() == null ? "" : Utils.addEntities(e.getLastName())) %>
|
||||
</td>
|
||||
<td headers="t4" class="<%= row %>RowEvenCol">
|
||||
<%= (e.getFirstName() == null ? "" : e.getFirstName()) %>
|
||||
<%= (e.getFirstName() == null ? "" : Utils.addEntities(e.getFirstName())) %>
|
||||
</td>
|
||||
<td headers="t5" class="<%= row %>RowOddCol" align="center">
|
||||
<%= e.canLogIn() ? "yes" : "no" %>
|
||||
@@ -130,7 +131,7 @@
|
||||
<%= e.getSelfRegistered() ? "yes" : "no" %>
|
||||
</td>
|
||||
<td headers="t8" class="<%= row %>RowEvenCol">
|
||||
<%= (e.getMetadata("phone") == null ? "" : e.getMetadata("phone")) %>
|
||||
<%= (e.getMetadata("phone") == null ? "" : Utils.addEntities(e.getMetadata("phone"))) %>
|
||||
</td>
|
||||
<td headers="t9" class="<%= row %>RowOddCol">
|
||||
<input type="hidden" name="eperson_id" value="<%= e.getID() %>"/>
|
||||
|
@@ -20,6 +20,7 @@
|
||||
prefix="fmt" %>
|
||||
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
|
||||
|
||||
@@ -32,9 +33,9 @@
|
||||
parenttitlekey="jsp.administer"
|
||||
parentlink="/dspace-admin">
|
||||
|
||||
<%-- <h1>Delete e-person: <%= eperson.getFullName() %> (<%= eperson.getEmail() %>)</h1> --%>
|
||||
<%-- <h1>Delete e-person: <%= Utils.addEntities(eperson.getFullName()) %> (<%= eperson.getEmail() %>)</h1> --%>
|
||||
<h1><fmt:message key="jsp.dspace-admin.eperson-confirm-delete.heading">
|
||||
<fmt:param><%= eperson.getFullName() %></fmt:param>
|
||||
<fmt:param><%= Utils.addEntities(eperson.getFullName()) %></fmt:param>
|
||||
<fmt:param><%= eperson.getEmail() %></fmt:param>
|
||||
</fmt:message></h1>
|
||||
|
||||
|
@@ -28,11 +28,12 @@
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="java.util.List" %>
|
||||
<%@ page import="java.util.Iterator" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%
|
||||
EPerson eperson = (EPerson) request.getAttribute("eperson");
|
||||
List tableList = (List) request.getAttribute("tableList");
|
||||
String fullName = eperson.getFullName();
|
||||
String fullName = Utils.addEntities(eperson.getFullName());
|
||||
Iterator tableIt = tableList.iterator();
|
||||
|
||||
%>
|
||||
|
@@ -28,6 +28,7 @@
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="org.dspace.eperson.Group" %>
|
||||
<%@ page import="org.dspace.content.WorkspaceItem" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%
|
||||
// get item and group out of the request
|
||||
@@ -75,7 +76,7 @@
|
||||
<br/><br/>
|
||||
<strong><fmt:message key="jsp.dspace-admin.supervise-confirm-remove.authorheader"/></strong>:
|
||||
<br/>
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a>
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
|
||||
<br/><br/>
|
||||
<strong><fmt:message key="jsp.dspace-admin.supervise-confirm-remove.supervisorgroupheader"/></strong>:
|
||||
<br/>
|
||||
|
@@ -28,6 +28,7 @@
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="org.dspace.eperson.Group" %>
|
||||
<%@ page import="org.dspace.eperson.Supervisor" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%
|
||||
// get objects from request
|
||||
@@ -109,7 +110,7 @@
|
||||
<%= workspaceItems[i].getID() %>
|
||||
</td>
|
||||
<td class="<%= row %>RowEvenCol">
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a>
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
|
||||
</td>
|
||||
<td class="<%= row %>RowOddCol">
|
||||
<%
|
||||
|
@@ -25,6 +25,7 @@
|
||||
<%@ page import="org.dspace.content.SupervisedItem" %>
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="org.dspace.eperson.Group" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%
|
||||
// get the object array out of the request
|
||||
@@ -97,7 +98,7 @@
|
||||
<%= supervisors[j].getName() %>
|
||||
</td>
|
||||
<td class="<%= row %>RowOddCol">
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a>
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
|
||||
</td>
|
||||
<td class="<%= row %>RowEvenCol">
|
||||
<%
|
||||
|
@@ -0,0 +1,52 @@
|
||||
<%--
|
||||
|
||||
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/
|
||||
|
||||
--%>
|
||||
<%--
|
||||
- Error page for when the file uploaded exceeded the size limit
|
||||
--%>
|
||||
|
||||
<%@ page contentType="text/html;charset=UTF-8" %>
|
||||
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"
|
||||
prefix="fmt" %>
|
||||
|
||||
<%@ page import="java.io.PrintWriter" %>
|
||||
|
||||
<%@ page isErrorPage="true" %>
|
||||
|
||||
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
|
||||
|
||||
<dspace:layout titlekey="jsp.error.exceeded-size.title">
|
||||
<h1><fmt:message key="jsp.error.exceeded-size.title"/></h1>
|
||||
<p>
|
||||
<fmt:message key="jsp.error.exceeded-size.text1">
|
||||
<fmt:param><%= request.getAttribute("actualSize") %></fmt:param>
|
||||
<fmt:param><%= request.getAttribute("permittedSize") %></fmt:param>
|
||||
</fmt:message>
|
||||
</p>
|
||||
|
||||
<dspace:include page="/components/contact-info.jsp" />
|
||||
|
||||
<p align="center">
|
||||
<a href="<%= request.getContextPath() %>/"><fmt:message key="jsp.general.gohome"/></a>
|
||||
</p>
|
||||
<!--
|
||||
<%
|
||||
String error = request.getAttribute("error.message").toString();
|
||||
if(error == null)
|
||||
{
|
||||
out.println("No stack trace available<br/>");
|
||||
}
|
||||
else
|
||||
{
|
||||
out.println(error);
|
||||
}
|
||||
%>
|
||||
-->
|
||||
</dspace:layout>
|
@@ -1,35 +1,35 @@
|
||||
====
|
||||
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/
|
||||
====
|
||||
The following icon files:
|
||||
- book_key.png
|
||||
- zoom.png
|
||||
- bug.png
|
||||
are taken from
|
||||
|
||||
Silk icon set 1.3
|
||||
|
||||
_________________________________________
|
||||
Mark James
|
||||
http://www.famfamfam.com/lab/icons/silk/
|
||||
_________________________________________
|
||||
|
||||
This work is licensed under a
|
||||
Creative Commons Attribution 2.5 License.
|
||||
[ http://creativecommons.org/licenses/by/2.5/ ]
|
||||
|
||||
This means you may use it for any purpose,
|
||||
and make any changes you like.
|
||||
All I ask is that you include a link back
|
||||
to this page in your credits.
|
||||
|
||||
Are you using this icon set? Send me an email
|
||||
(including a link or picture if available) to
|
||||
mjames@gmail.com
|
||||
|
||||
Any other questions about this icon set please
|
||||
====
|
||||
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/
|
||||
====
|
||||
The following icon files:
|
||||
- book_key.png
|
||||
- zoom.png
|
||||
- bug.png
|
||||
are taken from
|
||||
|
||||
Silk icon set 1.3
|
||||
|
||||
_________________________________________
|
||||
Mark James
|
||||
http://www.famfamfam.com/lab/icons/silk/
|
||||
_________________________________________
|
||||
|
||||
This work is licensed under a
|
||||
Creative Commons Attribution 2.5 License.
|
||||
[ http://creativecommons.org/licenses/by/2.5/ ]
|
||||
|
||||
This means you may use it for any purpose,
|
||||
and make any changes you like.
|
||||
All I ask is that you include a link back
|
||||
to this page in your credits.
|
||||
|
||||
Are you using this icon set? Send me an email
|
||||
(including a link or picture if available) to
|
||||
mjames@gmail.com
|
||||
|
||||
Any other questions about this icon set please
|
||||
contact mjames@gmail.com
|
@@ -1,53 +1,53 @@
|
||||
====
|
||||
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/
|
||||
====
|
||||
16x16 Free Application Icons
|
||||
|
||||
This icon set is free for use in personal and commercial projects.
|
||||
|
||||
License Agreement
|
||||
|
||||
By purchasing icons from Aha-Soft, You (the purchaser)
|
||||
agree to the terms of this agreement, as detailed below.
|
||||
|
||||
You may use the icons from Aha-Soft in commercial and
|
||||
personal design projects, software or Internet products.
|
||||
Icons can be displayed in documentation, help files, and
|
||||
advertising materials. You are free to sell and distribute
|
||||
products and projects using purchased icons without further
|
||||
royalty fees.
|
||||
|
||||
All icon files are provided 'as is'. Aha-Soft cannot be
|
||||
held liable for any negative issues that may occur as a
|
||||
result of using the icons.
|
||||
|
||||
You agree that all ownership and copyright of the icons
|
||||
remains the property of Aha-Soft. You may not resell,
|
||||
distribute, lease, license or sub-license the icons or
|
||||
modified icons (or a subset of the icons), to any third
|
||||
party unless they are incorporated into your software or
|
||||
design products.
|
||||
|
||||
If you have any questions regarding copyright or licensing,
|
||||
including whether another license is required for icon use
|
||||
within products, please contact us here: www.aha-soft.com/support.htm
|
||||
|
||||
Product page: http://www.small-icons.com/stock-icons/16x16-free-application-icons.htm
|
||||
|
||||
Icon Design Service
|
||||
|
||||
We can design custom icons for you. Please find the basic information
|
||||
about ordering icons, pricing and the portfolio here:
|
||||
www.aha-soft.com/customdev/design.htm
|
||||
|
||||
|
||||
Notice
|
||||
Web-site small-icons.com belongs to Aha-Soft.
|
||||
|
||||
Support page: http://www.aha-soft.com/support.htm
|
||||
|
||||
====
|
||||
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/
|
||||
====
|
||||
16x16 Free Application Icons
|
||||
|
||||
This icon set is free for use in personal and commercial projects.
|
||||
|
||||
License Agreement
|
||||
|
||||
By purchasing icons from Aha-Soft, You (the purchaser)
|
||||
agree to the terms of this agreement, as detailed below.
|
||||
|
||||
You may use the icons from Aha-Soft in commercial and
|
||||
personal design projects, software or Internet products.
|
||||
Icons can be displayed in documentation, help files, and
|
||||
advertising materials. You are free to sell and distribute
|
||||
products and projects using purchased icons without further
|
||||
royalty fees.
|
||||
|
||||
All icon files are provided 'as is'. Aha-Soft cannot be
|
||||
held liable for any negative issues that may occur as a
|
||||
result of using the icons.
|
||||
|
||||
You agree that all ownership and copyright of the icons
|
||||
remains the property of Aha-Soft. You may not resell,
|
||||
distribute, lease, license or sub-license the icons or
|
||||
modified icons (or a subset of the icons), to any third
|
||||
party unless they are incorporated into your software or
|
||||
design products.
|
||||
|
||||
If you have any questions regarding copyright or licensing,
|
||||
including whether another license is required for icon use
|
||||
within products, please contact us here: www.aha-soft.com/support.htm
|
||||
|
||||
Product page: http://www.small-icons.com/stock-icons/16x16-free-application-icons.htm
|
||||
|
||||
Icon Design Service
|
||||
|
||||
We can design custom icons for you. Please find the basic information
|
||||
about ordering icons, pricing and the portfolio here:
|
||||
www.aha-soft.com/customdev/design.htm
|
||||
|
||||
|
||||
Notice
|
||||
Web-site small-icons.com belongs to Aha-Soft.
|
||||
|
||||
Support page: http://www.aha-soft.com/support.htm
|
||||
|
||||
Copyright <20> 2009 Aha-Soft. All rights reserved.
|
@@ -25,7 +25,6 @@
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"
|
||||
prefix="fmt" %>
|
||||
|
||||
|
||||
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
|
||||
|
||||
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %>
|
||||
@@ -78,7 +77,7 @@
|
||||
<tr>
|
||||
<td align="left">
|
||||
<h1>
|
||||
<fmt:message key="jsp.mydspace"/>: <%= user.getFullName() %>
|
||||
<fmt:message key="jsp.mydspace"/>: <%= Utils.addEntities(user.getFullName()) %>
|
||||
</h1>
|
||||
</td>
|
||||
<td align="right" class="standard">
|
||||
@@ -136,7 +135,7 @@
|
||||
</td>
|
||||
<td headers="t2" class="<%= row %>RowEvenCol"><%= Utils.addEntities(title) %></td>
|
||||
<td headers="t3" class="<%= row %>RowOddCol"><%= owned[i].getCollection().getMetadata("name") %></td>
|
||||
<td headers="t4" class="<%= row %>RowEvenCol"><a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a></td>
|
||||
<td headers="t4" class="<%= row %>RowEvenCol"><a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a></td>
|
||||
<!-- <td headers="t5" class="<%= row %>RowOddCol"></td> -->
|
||||
<td headers="t5" class="<%= row %>RowEvenCol">
|
||||
<form action="<%= request.getContextPath() %>/mydspace" method="post">
|
||||
@@ -200,7 +199,7 @@
|
||||
</td>
|
||||
<td headers="t7" class="<%= row %>RowEvenCol"><%= Utils.addEntities(title) %></td>
|
||||
<td headers="t8" class="<%= row %>RowOddCol"><%= pooled[i].getCollection().getMetadata("name") %></td>
|
||||
<td headers="t9" class="<%= row %>RowEvenCol"><a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a></td>
|
||||
<td headers="t9" class="<%= row %>RowEvenCol"><a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a></td>
|
||||
<td class="<%= row %>RowOddCol">
|
||||
<form action="<%= request.getContextPath() %>/mydspace" method="post">
|
||||
<input type="hidden" name="step" value="<%= MyDSpaceServlet.MAIN_PAGE %>" />
|
||||
@@ -285,7 +284,7 @@
|
||||
</form>
|
||||
</td>
|
||||
<td headers="t10" class="<%= row %>RowEvenCol">
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a>
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
|
||||
</td>
|
||||
<td headers="t11" class="<%= row %>RowOddCol"><%= Utils.addEntities(title) %></td>
|
||||
<td headers="t12" class="<%= row %>RowEvenCol"><%= workspaceItems[i].getCollection().getMetadata("name") %></td>
|
||||
@@ -332,7 +331,7 @@
|
||||
</form>
|
||||
</td>
|
||||
<td class="<%= row %>RowEvenCol">
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a>
|
||||
<a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
|
||||
</td>
|
||||
<td class="<%= row %>RowOddCol"><%= Utils.addEntities(title) %></td>
|
||||
<td class="<%= row %>RowEvenCol"><%= supervisedItems[i].getCollection().getMetadata("name") %></td>
|
||||
|
@@ -29,6 +29,7 @@
|
||||
|
||||
<%@ page import="org.dspace.app.webui.servlet.RegisterServlet" %>
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%
|
||||
EPerson eperson = (EPerson) request.getAttribute("eperson");
|
||||
@@ -43,9 +44,9 @@
|
||||
<%-- <h1>Enter a New Password</h1> --%>
|
||||
<h1><fmt:message key="jsp.register.new-password.title"/></h1>
|
||||
|
||||
<!-- <p>Hello <%= eperson.getFullName() %>,</p> -->
|
||||
<!-- <p>Hello <%= Utils.addEntities(eperson.getFullName()) %>,</p> -->
|
||||
<p><fmt:message key="jsp.register.new-password.hello">
|
||||
<fmt:param><%= eperson.getFullName() %></fmt:param>
|
||||
<fmt:param><%= Utils.addEntities(eperson.getFullName()) %></fmt:param>
|
||||
</fmt:message></p>
|
||||
|
||||
<%
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
<%@ page import="org.dspace.app.webui.servlet.RegisterServlet" %>
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%
|
||||
EPerson eperson = (EPerson) request.getAttribute("eperson");
|
||||
@@ -35,9 +36,9 @@
|
||||
<%-- <h1>Registration Complete</h1> --%>
|
||||
<h1><fmt:message key="jsp.register.registered.title"/></h1>
|
||||
|
||||
<%-- <p>Thank you <%= eperson.getFirstName() %>,</p> --%>
|
||||
<%-- <p>Thank you <%= Utils.addEntities(eperson.getFirstName()) %>,</p> --%>
|
||||
<p><fmt:message key="jsp.register.registered.thank">
|
||||
<fmt:param><%= eperson.getFirstName() %></fmt:param>
|
||||
<fmt:param><%= Utils.addEntities(eperson.getFirstName()) %></fmt:param>
|
||||
</fmt:message></p>
|
||||
|
||||
<%-- <p>You're now registered to use the DSpace system. You can subscribe to
|
||||
|
@@ -50,6 +50,7 @@
|
||||
<%@ page import="org.dspace.content.authority.ChoiceAuthorityManager" %>
|
||||
<%@ page import="org.dspace.content.authority.Choices" %>
|
||||
<%@ page import="org.dspace.core.ConfigurationManager" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
|
||||
@@ -325,9 +326,9 @@
|
||||
if (repeatable && !readonly && i < defaults.length)
|
||||
{
|
||||
name.setLength(0);
|
||||
name.append(dpn.getLastName())
|
||||
name.append(Utils.addEntities(dpn.getLastName()))
|
||||
.append(' ')
|
||||
.append(dpn.getFirstNames());
|
||||
.append(Utils.addEntities(dpn.getFirstNames()));
|
||||
// put a remove button next to filled in values
|
||||
sb.append("<td><input type=\"submit\" name=\"submit_")
|
||||
.append(fieldName)
|
||||
|
@@ -281,7 +281,7 @@ function clearEPeople()
|
||||
{
|
||||
EPerson e = epeople[i];
|
||||
// Make sure no quotes in full name will mess up our Javascript
|
||||
String fullname = e.getFullName().replace('\'', ' ');
|
||||
String fullname = Utils.addEntities(e.getFullName().replace('\'', ' '));
|
||||
%>
|
||||
<tr>
|
||||
<td headers="t1" class="<%= row %>RowOddCol">
|
||||
@@ -291,10 +291,10 @@ function clearEPeople()
|
||||
<td headers="t2" class="<%= row %>RowEvenCol"><%= e.getID() %></td>
|
||||
<td headers="t3" class="<%= row %>RowOddCol"><%= e.getEmail() %></td>
|
||||
<td headers="t4" class="<%= row %>RowEvenCol">
|
||||
<%= (e.getLastName() == null ? "" : e.getLastName()) %>
|
||||
<%= (e.getLastName() == null ? "" : Utils.addEntities(e.getLastName())) %>
|
||||
</td>
|
||||
<td headers="t5" class="<%= row %>RowOddCol">
|
||||
<%= (e.getFirstName() == null ? "" : e.getFirstName()) %>
|
||||
<%= (e.getFirstName() == null ? "" : Utils.addEntities(e.getFirstName())) %>
|
||||
</td>
|
||||
<td headers="t6" class="<%= row %>RowOddCol">
|
||||
<%= (e.getLanguage() == null ? "" : e.getLanguage()) %>
|
||||
|
@@ -26,6 +26,7 @@
|
||||
<%@ page import="org.dspace.content.WorkspaceItem" %>
|
||||
<%@ page import="org.dspace.eperson.EPerson" %>
|
||||
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %>
|
||||
<%@ page import="org.dspace.core.Utils" %>
|
||||
|
||||
<%
|
||||
// get the workspace item from the request
|
||||
@@ -73,7 +74,7 @@
|
||||
}
|
||||
%>
|
||||
|
||||
<p><strong><a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a></strong></p>
|
||||
<p><strong><a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a></strong></p>
|
||||
|
||||
<p><fmt:message key="jsp.workspace.ws-main.submitmsg"/>
|
||||
<%= workspaceItem.getCollection().getMetadata("name") %></p>
|
||||
|
@@ -14,19 +14,14 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update against
|
||||
when changes have occured, this spawns a new build cycle and releases snapshots
|
||||
into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui</connection>
|
||||
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-jspui</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>dspace-jspui-api</module>
|
||||
|
@@ -12,14 +12,14 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-lni</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-client</connection>
|
||||
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-client</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-client</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/../..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
@@ -82,6 +82,16 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--Exclude license check for LNI files which don't need it-->
|
||||
<excludes>
|
||||
<exclude>**/*.wsdl</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!--
|
||||
This is another approach to packaging the LNI client that may be approached.
|
||||
@@ -183,4 +193,4 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@@ -10,14 +10,14 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-lni</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-core</connection>
|
||||
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-core</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-core</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/../..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -64,4 +64,4 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@@ -12,14 +12,14 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-lni</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-webapp</connection>
|
||||
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-webapp</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-webapp</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/../..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
@@ -46,6 +46,16 @@
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<configuration>
|
||||
<!--Exclude license check for LNI files which don't need it-->
|
||||
<excludes>
|
||||
<exclude>**/*.wsdd</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
@@ -109,4 +119,4 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@@ -12,19 +12,14 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>1.7.1-SNAPSHOT</version>
|
||||
<version>1.7.4-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<!--
|
||||
The Subversion repository location is used by Continuum to update against
|
||||
when changes have occured, this spawns a new build cycle and releases snapshots
|
||||
into the snapshot repository below.
|
||||
-->
|
||||
<scm>
|
||||
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni</connection>
|
||||
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni</developerConnection>
|
||||
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni</url>
|
||||
</scm>
|
||||
<properties>
|
||||
<!-- This is the path to the root [dspace-src] directory. -->
|
||||
<root.basedir>${basedir}/..</root.basedir>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>dspace-lni-core</module>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user