Compare commits

...

73 Commits

Author SHA1 Message Date
Ivan Masár
99f11afc00 DS-1605 add .travis.yml for Travis-CI integration 2013-07-25 16:39:25 +02:00
Hardy Pottinger
d1afd58c7d [maven-release-plugin] prepare for next development iteration 2013-07-25 08:45:20 -05:00
Hardy Pottinger
96184cad90 [maven-release-plugin] prepare release dspace-1.7.3 2013-07-25 08:45:15 -05:00
Hardy Pottinger
e782449835 backporting patch to DS-1603 to dspace 1.7 2013-07-24 16:28:46 -05:00
Tim Donohue
a993c9a3c1 More line ending normalization (related to DS-1587) 2013-07-23 21:30:33 +00:00
Tim Donohue
23da4c607c Line ending normalization (related to DS-1587) 2013-07-23 21:19:05 +00:00
Tim Donohue
1bf23d7c4c License Header fixes (related to DS-1587). Fix pom.xml configs to skip files not needing checking 2013-06-26 14:51:40 -05:00
Tim Donohue
38ef9080fa Backporting DS-1587 : Cleanup POMs to work with GitHub and also merge in old "dspace-pom" functionality into dspace-parent POM.
Also includes fixes for DS-1588 : Ensure 1.7.x now builds properly with Maven 3.
2013-06-26 13:04:37 -05:00
Tim Donohue
17be1b9c25 Fix line endings (related to DS-1587) 2013-06-26 10:45:22 -05:00
Tim Donohue
deaf6a5d82 DS-1587 - Commit .gitignore files and .gitattributes 2013-06-26 10:20:50 -05:00
Peter Dietz
16b5ebfdea [maven-release-plugin] prepare for next development iteration
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6398 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-27 17:44:19 +00:00
Peter Dietz
e320ebd85a [maven-release-plugin] prepare release dspace-1.7.2
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6396 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-27 17:44:03 +00:00
Peter Dietz
e8d7f30ccf [maven-release-plugin] rollback the release of dspace-1.7.2
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6395 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-27 17:35:25 +00:00
Peter Dietz
36fa23246c [maven-release-plugin] prepare release dspace-1.7.2
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6394 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-27 17:30:33 +00:00
Peter Dietz
ca21676305 [maven-release-plugin] rollback the release of dspace-1.7.2
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6393 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-27 17:16:56 +00:00
Peter Dietz
266ec0fc2b [maven-release-plugin] prepare release dspace-1.7.2
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6391 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-27 16:55:00 +00:00
Peter Dietz
7e1e0ce8b5 Added 1.7.2 known bugs entry. Fixed typo in NOTICE.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6389 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-27 15:40:12 +00:00
Peter Dietz
faf8883bc9 [DS-841] No such column rnum error in eperson admin with Oracle backend. (Patch by Hardy Pottinger).
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6387 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-27 14:27:44 +00:00
Mark Diggory
43fc41fef9 [DS-875] DSpace Configuration service error when using "dspace" script. ( provided by kevin@atmire.com )
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6385 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-25 20:46:44 +00:00
Peter Dietz
d863d8a88c [DS-871] Fix XMLUI Caching for community and collection recent submissions
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6381 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-05-16 18:37:34 +00:00
Peter Dietz
21f7f3f9ca [maven-release-plugin] prepare for next development iteration
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6278 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 16:18:28 +00:00
Peter Dietz
37a6f5e82a [maven-release-plugin] prepare release dspace-1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6276 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 16:18:10 +00:00
Tim Donohue
f6f0104cd4 Fix to 1.7.x Branch's main pom.xml. Somehow, all its SCM settings still pointed at Trunk, rather than at this Branch. This caused issues during release tagging, as releases kept being tagged off of *Trunk* rather than the Branch.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6274 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 15:49:52 +00:00
Tim Donohue
4e6973a569 [maven-release-plugin] rollback the release of dspace-1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6272 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 15:45:22 +00:00
Tim Donohue
aa8dd60640 [maven-release-plugin] prepare for next development iteration
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6271 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 15:34:06 +00:00
Tim Donohue
b997ca866f [maven-release-plugin] prepare release dspace-1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6269 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 15:33:39 +00:00
Peter Dietz
5c6c7e1fd1 [maven-release-plugin] rollback the release of dspace-1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6267 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 14:42:27 +00:00
Peter Dietz
6e026ed6fd [maven-release-plugin] prepare for next development iteration
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6266 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 14:33:00 +00:00
Peter Dietz
c3a48caca4 [maven-release-plugin] prepare release dspace-1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6264 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 14:32:43 +00:00
Peter Dietz
39538b1ab8 Regenerated Docs to account for changes in DS-860
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6263 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 13:58:59 +00:00
Kim Shepherd
f923f7c391 [DS-860] SWORD still uses dspace.url rather than dspace.baseUrl
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6261 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-28 08:29:29 +00:00
Mark Diggory
97e105b88f [DSCR-4] Add AJAX term suggestion against Solr to Search for fields. (Made finding location of JSON more robust)
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6258 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-26 16:14:50 +00:00
Mark Diggory
4eaacd90cb [DSCR-20] Fix Broken Related Items Section
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6257 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-26 07:49:14 +00:00
Mark Diggory
9a075ac5d9 Next release of dspace-pom without broken goals section
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6255 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 22:41:01 +00:00
Tim Donohue
f43e2e2992 Undoing last change
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6249 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 21:00:13 +00:00
Tim Donohue
06b81964e4 Wrapping <goal> within <goals> -- we had invalid settings for maven-release-plugin
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6248 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 20:55:03 +00:00
Peter Dietz
84042ce512 [maven-release-plugin] rollback the release of dspace-parent-1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6246 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 20:44:17 +00:00
Peter Dietz
3c7d8ba607 Wrapped goal inside of goals.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6245 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 20:33:27 +00:00
Peter Dietz
151afeace5 [maven-release-plugin] prepare for next development iteration
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6244 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 20:29:00 +00:00
Peter Dietz
aa6f1baa4a [maven-release-plugin] prepare release dspace-parent-1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6242 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 20:28:40 +00:00
Peter Dietz
2b67c5ccb2 [maven-release-plugin] prepare for next development iteration
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6241 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 20:11:55 +00:00
Peter Dietz
06878eab58 [maven-release-plugin] prepare release dspace-parent-1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6239 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 20:11:37 +00:00
Peter Dietz
7cc9a5d3d0 Added PDF System Documentation for 1.7.1
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6238 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 19:38:46 +00:00
Peter Dietz
8237d8b6e1 Added 1.7.1 html documentation.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6237 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 19:31:22 +00:00
Peter Dietz
48777df275 Removed 1.7.0 html documentation.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6236 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 19:21:13 +00:00
Tim Donohue
908429570c Updates to all README & LICENSE files in preparation for 1.7.1 release. These updates included minor changes to links, changes to the License date range, and spelling corrections.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6233 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 17:12:43 +00:00
Tim Donohue
d999d0b0b7 Fix for DS-857 - CHANGES file now obsolete in SVN - point at online History
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6231 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 17:06:49 +00:00
Mark Diggory
2bfd77e634 Latest Fixed Solr Implementation
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6229 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 03:16:40 +00:00
Mark Diggory
0a50305ff5 Suppress Site Deployment as it is lengthy and error prone
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6209 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-25 00:03:27 +00:00
Mark Diggory
0bf155628d [DSRV-12] DSpace Configuration service reads in more configuration files - Commit for Kevin Van de Velde
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6196 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-24 23:48:45 +00:00
Kim Shepherd
1bbea4dbc4 [DS-785] SWORD deposits fail when ingest events are fired if Discovery event consumer is configured
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6176 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-23 07:11:41 +00:00
Kim Shepherd
edb6a8a86f [DS-853] MetadataExposure settings for dc.description.provenance are ignored/overridden by XMLUI templates
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6171 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-22 03:21:38 +00:00
Peter Dietz
491ca830a9 [DS-641] Page does not exist
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6164 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-16 23:06:53 +00:00
Peter Dietz
09e049739f [DS-620] Exceed maximum while uploading files got the user stuck should lead to a friendly error page
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6158 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-16 19:34:52 +00:00
Ben Bosman
0a00a8bbe9 [DS-843] Autocomplete in authority control contains small errors in Mirage
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6144 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-16 16:46:07 +00:00
Peter Dietz
0cbeef4010 [DS-776] Collection admin cannot add bitstreams unless there is at least one bundle.
Additionally did whitespace and formatting fix to the file being touched.

git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6143 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-15 18:45:52 +00:00
Mark Diggory
27ae52c8f1 [DS-840] Add Ability to create Top Level Community in at the home page, additional support to force discovery facets to be just under search.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6141 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-15 06:51:06 +00:00
Mark Diggory
2834c8ccf6 [DS-840] Add Ability to create Top Level Community in at the home page.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6140 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-15 06:32:25 +00:00
Mark Diggory
1a9a7dfcba [DSCR-19] Case sensitive sidebar facets
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6139 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-15 05:52:34 +00:00
Mark Diggory
27741e59a9 [DS-839] Adding Field to Choice Authority to allow Authorities to be able to know of the field being authority controlled.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6138 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-15 05:26:02 +00:00
Tim Donohue
1f4e370234 DS-821 fix (AbstractMETSIngester creates an item before adding descriptive metadata). This fix essentially reorganizes logic in AbstractMETSIngester.ingestObject(), to ensure that item is not officially *installed* in DSpace until all of the Descriptive Metadata crosswalks and files are attached. See DS-821 for more info. I've tested this fix via both SWORD ingest and via AIP Ingest, and both seem to work perfectly.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6137 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-14 19:11:56 +00:00
Robin Taylor
f8c0886738 [DS-435] - Prevent MyExports link appearing when not logged on.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6110 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-05 10:56:02 +00:00
Stuart Lewis
296a70b4d8 [DS-215] Single-argument Item.getMetadata does not work with mixed-case metadata terms. Re-applied in 1.7.1 / 1.8(trunk) as it got overwritten during a merge in the 1.7 development.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6107 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-03-04 03:20:04 +00:00
Ben Bosman
c0f8854398 [DS-823] DatabaseManager Oracle compliance
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6092 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-02-24 12:47:24 +00:00
Mark Diggory
f7e2723e5c [DSCR-18] Corrections to allow full text indexing provided by Kevin Van de Velde
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6082 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-02-18 07:54:24 +00:00
Stuart Lewis
314011e069 [DS-806] Item.match() incorrect logic for schema testing
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6052 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-01-27 00:51:49 +00:00
Stuart Lewis
aa708a326c [DS-806] junit test - should cause bamboo to report a test failure. Patch to fix this to be applied shortly.
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6051 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-01-27 00:47:30 +00:00
Ben Bosman
ce3a2098e4 [DS-809] Support for empty dc.abstract dim field in Internet Explorer
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6045 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-01-25 16:37:40 +00:00
Ben Bosman
28bf3e3046 [DS-808] jqueryUI javascript gets imported without corresponding CSS
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6042 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-01-25 16:33:25 +00:00
Claudia Juergen
793974234d [DS-761] MetadataSchema: cache out of sync after calling delete()
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6027 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-01-19 15:29:06 +00:00
Peter Dietz
7ea045b2ed [DS-789] HTTPS renders with errors due to a hardcoded HTTP link
Added a detection for https/http so that when loading JS from CDN uses same protocol, thus solving mixed content warning.

git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6017 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-01-13 17:58:09 +00:00
Claudia Juergen
54d0316724 [DS-758] Mirage theme - lists of unifished submission/workflow task wrong link in collection column
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@6012 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2011-01-07 14:29:33 +00:00
Tim Donohue
77573bc55f Creating a branch for any necessary 1.7.x bug-fix releases
git-svn-id: http://scm.dspace.org/svn/repo/dspace/branches/dspace-1_7_x@5992 9c30dcfa-912a-0410-8fc2-9e0234be79fd
2010-12-16 18:58:44 +00:00
211 changed files with 22820 additions and 23223 deletions

14
.gitattributes vendored Normal file
View 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
View 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
View File

@@ -0,0 +1 @@
language: java

View File

@@ -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
View 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
View File

@@ -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
View File

@@ -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.

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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))
{

View File

@@ -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();
}
}

View File

@@ -354,6 +354,7 @@ public class MetadataSchema
"metadata_schema_id=" + getSchemaID()));
DatabaseManager.delete(context, row);
decache();
}
/**

View File

@@ -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
*

View File

@@ -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);
}

View File

@@ -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);
}
/**

View File

@@ -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)];

View File

@@ -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("");
}
}
}
}

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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)];
}

View File

@@ -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);
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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);
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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);
}
}
}

View File

@@ -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());
}
}
}

View File

@@ -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);
}

View File

@@ -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("");
}
}
}
}

View File

@@ -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())

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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)";
}
}

View File

@@ -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
*/

View File

@@ -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("&", "&amp;");
value = value.replaceAll("\"", "&quot;");
// actually, &apos; is an XML entity, not in HTML.
// that's why it's commented out.
// value = value.replaceAll("'", "&apos;");
value = value.replaceAll("<", "&lt;");
value = value.replaceAll(">", "&gt;");
return value;
return Escape.html(value);
}
/**

View File

@@ -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);
}
}
}

View File

@@ -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());

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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));

View File

@@ -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

View File

@@ -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.
*/

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;

View File

@@ -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() + " "

View File

@@ -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>

View File

@@ -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() + ")"
);
}

View File

@@ -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");
}
/**

View File

@@ -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());

View File

@@ -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() + ")"
);
}
}

View File

@@ -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 .*?)\\]");

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);
}
/**

View File

@@ -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);

View File

@@ -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();
}
/**

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -87,7 +87,7 @@ public class WithdrawnBrowserServlet extends AbstractBrowserServlet
{
request.setAttribute("useAdminLayout", "yes");
JSPManager.showJSP(request, response, "/browse/error.jsp");
JSPManager.showInternalError(request, response);
}
/**

View File

@@ -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;
}
}
}

View File

@@ -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");
}
}

View File

@@ -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>

View File

@@ -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() %>"/>

View File

@@ -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>

View File

@@ -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();
%>

View File

@@ -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/>

View File

@@ -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">
<%

View File

@@ -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">
<%

View File

@@ -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>

View File

@@ -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

View File

@@ -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.

View File

@@ -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>

View File

@@ -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>
<%

View File

@@ -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

View File

@@ -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)

View File

@@ -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()) %>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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