Compare commits

...

71 Commits

Author SHA1 Message Date
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
210 changed files with 22819 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/

View File

@@ -1,7 +1,7 @@
DSpace source code license: 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 Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are 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 the legal copyright from Hewlett-Packard Company (HP) and Massachusetts
Institute of Technology (MIT) to the DSpace Foundation in October 2007. Many 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 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 and MIT possess the copyright, in these instances please note that the copy
right has transfered to the DSpace foundation, and subsequently to Duraspace. 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/docs/pdf/DSpace-Manual.pdf
DSpace version information can be found in this release package under DSpace version information can be found in this release package under
- dspace/CHANGES
or
- dspace/docs/html/History.html - 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 Documentation for the most recent stable release(s) may be downloaded
or viewed online at or viewed online at
@@ -31,12 +31,12 @@ mailing list.
Detailed Issue Tracking for DSpace is done on our JIRA Issue Tracker 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: 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, 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: DSpace source code licensing information available online at:
- http://www.dspace.org/license/ - 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 A Parent POM that Maven inherits DSpace Defaults
POM atrributes from. POM attributes from.
--> -->
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-parent</artifactId> <artifactId>dspace-parent</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<!-- <properties>
The Subversion repository location is used by Continuum to update against <!-- This is the path to the root [dspace-src] directory. -->
when changes have occured, this spawns a new build cycle and releases snapshots <root.basedir>${basedir}/..</root.basedir>
into the snapshot repository below. </properties>
-->
<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>
<!-- <!--
Runtime and Compile Time dependencies for DSpace. Runtime and Compile Time dependencies for DSpace.
@@ -60,29 +55,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </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> </plugins>
</build> </build>
<dependencies> <dependencies>
@@ -277,6 +249,16 @@
<artifactId>contiperf</artifactId> <artifactId>contiperf</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </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> </project>

View File

@@ -1,338 +1,338 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.app.bulkedit; package org.dspace.app.bulkedit;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.DCValue; import org.dspace.content.DCValue;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* Utility class to store changes to item that may occur during a batch edit. * Utility class to store changes to item that may occur during a batch edit.
* *
* @author Stuart Lewis * @author Stuart Lewis
*/ */
public class BulkEditChange public class BulkEditChange
{ {
/** The item these changes relate to */ /** The item these changes relate to */
private Item item; private Item item;
/** The List of hashtables with the new elements */ /** The List of hashtables with the new elements */
private List<DCValue> adds; private List<DCValue> adds;
/** The List of hashtables with the removed elements */ /** The List of hashtables with the removed elements */
private List<DCValue> removes; private List<DCValue> removes;
/** The List of hashtables with the unchanged elements */ /** The List of hashtables with the unchanged elements */
private List<DCValue> constant; private List<DCValue> constant;
/** The List of the complete set of new values (constant + adds) */ /** The List of the complete set of new values (constant + adds) */
private List<DCValue> complete; private List<DCValue> complete;
/** The list of old collections the item used to be mapped to */ /** The list of old collections the item used to be mapped to */
private List<Collection> oldMappedCollections; private List<Collection> oldMappedCollections;
/** The list of new collections the item has been mapped into */ /** The list of new collections the item has been mapped into */
private List<Collection> newMappedCollections; private List<Collection> newMappedCollections;
/** The old owning collection */ /** The old owning collection */
private Collection oldOwningCollection; private Collection oldOwningCollection;
/** The new owning collection */ /** The new owning collection */
private Collection newOwningCollection; private Collection newOwningCollection;
/** Is this a new item */ /** Is this a new item */
private boolean newItem; private boolean newItem;
/** Have any changes actually been made? */ /** Have any changes actually been made? */
private boolean empty; private boolean empty;
/** /**
* Initialise a change holder for a new item * Initialise a change holder for a new item
*/ */
public BulkEditChange() public BulkEditChange()
{ {
// Set the item to be null // Set the item to be null
item = null; item = null;
newItem = true; newItem = true;
empty = true; empty = true;
oldOwningCollection = null; oldOwningCollection = null;
newOwningCollection = null; newOwningCollection = null;
// Initialise the arrays // Initialise the arrays
adds = new ArrayList<DCValue>(); adds = new ArrayList<DCValue>();
removes = new ArrayList<DCValue>(); removes = new ArrayList<DCValue>();
constant = new ArrayList<DCValue>(); constant = new ArrayList<DCValue>();
complete = new ArrayList<DCValue>(); complete = new ArrayList<DCValue>();
oldMappedCollections = new ArrayList<Collection>(); oldMappedCollections = new ArrayList<Collection>();
newMappedCollections = new ArrayList<Collection>(); newMappedCollections = new ArrayList<Collection>();
} }
/** /**
* Initialise a new change holder for an existing item * Initialise a new change holder for an existing item
* *
* @param i The Item to store * @param i The Item to store
*/ */
public BulkEditChange(Item i) public BulkEditChange(Item i)
{ {
// Store the item // Store the item
item = i; item = i;
newItem = false; newItem = false;
empty = true; empty = true;
// Initialise the arrays // Initialise the arrays
adds = new ArrayList<DCValue>(); adds = new ArrayList<DCValue>();
removes = new ArrayList<DCValue>(); removes = new ArrayList<DCValue>();
constant = new ArrayList<DCValue>(); constant = new ArrayList<DCValue>();
complete = new ArrayList<DCValue>(); complete = new ArrayList<DCValue>();
oldMappedCollections = new ArrayList<Collection>(); oldMappedCollections = new ArrayList<Collection>();
newMappedCollections = new ArrayList<Collection>(); newMappedCollections = new ArrayList<Collection>();
} }
/** /**
* Store the item - used when a new item is created * Store the item - used when a new item is created
* *
* @param i The item * @param i The item
*/ */
public void setItem(Item i) public void setItem(Item i)
{ {
// Store the item // Store the item
item = i; item = i;
} }
/** /**
* Add an added metadata value * Add an added metadata value
* *
* @param dcv The value to add * @param dcv The value to add
*/ */
public void registerAdd(DCValue dcv) public void registerAdd(DCValue dcv)
{ {
// Add the added value // Add the added value
adds.add(dcv); adds.add(dcv);
complete.add(dcv); complete.add(dcv);
empty = false; empty = false;
} }
/** /**
* Add a removed metadata value * Add a removed metadata value
* *
* @param dcv The value to remove * @param dcv The value to remove
*/ */
public void registerRemove(DCValue dcv) public void registerRemove(DCValue dcv)
{ {
// Add the removed value // Add the removed value
removes.add(dcv); removes.add(dcv);
empty = false; empty = false;
} }
/** /**
* Add an unchanged metadata value * Add an unchanged metadata value
* *
* @param dcv The value to keep unchanged * @param dcv The value to keep unchanged
*/ */
public void registerConstant(DCValue dcv) public void registerConstant(DCValue dcv)
{ {
// Add the removed value // Add the removed value
constant.add(dcv); constant.add(dcv);
complete.add(dcv); complete.add(dcv);
} }
/** /**
* Add a new mapped Collection * Add a new mapped Collection
* *
* @param c The new mapped Collection * @param c The new mapped Collection
*/ */
public void registerNewMappedCollection(Collection c) public void registerNewMappedCollection(Collection c)
{ {
// Add the new owning Collection // Add the new owning Collection
newMappedCollections.add(c); newMappedCollections.add(c);
empty = false; empty = false;
} }
/** /**
* Add an old mapped Collection * Add an old mapped Collection
* *
* @param c The old mapped Collection * @param c The old mapped Collection
*/ */
public void registerOldMappedCollection(Collection c) public void registerOldMappedCollection(Collection c)
{ {
// Add the old owning Collection (if it isn't there already, or is an old collection) // Add the old owning Collection (if it isn't there already, or is an old collection)
boolean found = false; boolean found = false;
if ((this.getOldOwningCollection() != null) && if ((this.getOldOwningCollection() != null) &&
(this.getOldOwningCollection().getHandle().equals(c.getHandle()))) (this.getOldOwningCollection().getHandle().equals(c.getHandle())))
{ {
found = true; found = true;
} }
for (Collection collection : oldMappedCollections) for (Collection collection : oldMappedCollections)
{ {
if (collection.getHandle().equals(c.getHandle())) if (collection.getHandle().equals(c.getHandle()))
{ {
found = true; found = true;
} }
} }
if (!found) if (!found)
{ {
oldMappedCollections.add(c); oldMappedCollections.add(c);
empty = false; empty = false;
} }
} }
/** /**
* Register a change to the owning collection * Register a change to the owning collection
* *
* @param oldC The old owning collection * @param oldC The old owning collection
* @param newC The new owning collection * @param newC The new owning collection
*/ */
public void changeOwningCollection(Collection oldC, Collection newC) public void changeOwningCollection(Collection oldC, Collection newC)
{ {
// Store the old owning collection // Store the old owning collection
oldOwningCollection = oldC; oldOwningCollection = oldC;
// Store the new owning collection // Store the new owning collection
newOwningCollection = newC; newOwningCollection = newC;
empty = false; empty = false;
} }
/** /**
* Set the owning collection of an item * Set the owning collection of an item
* *
* @param newC The new owning collection * @param newC The new owning collection
*/ */
public void setOwningCollection(Collection newC) public void setOwningCollection(Collection newC)
{ {
// Store the new owning collection // Store the new owning collection
newOwningCollection = newC; newOwningCollection = newC;
//empty = false; //empty = false;
} }
/** /**
* Get the DSpace Item that these changes are applicable to. * Get the DSpace Item that these changes are applicable to.
* *
* @return The item * @return The item
*/ */
public Item getItem() public Item getItem()
{ {
// Return the item // Return the item
return item; return item;
} }
/** /**
* Get the list of elements and their values that have been added. * Get the list of elements and their values that have been added.
* *
* @return 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() public List<DCValue> getAdds()
{ {
// Return the array // Return the array
return adds; return adds;
} }
/** /**
* Get the list of elements and their values that have been removed. * Get the list of elements and their values that have been removed.
* *
* @return 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() public List<DCValue> getRemoves()
{ {
// Return the array // Return the array
return removes; return removes;
} }
/** /**
* Get the list of unchanged values * Get the list of unchanged values
* *
* @return the list of unchanged values * @return the list of unchanged values
*/ */
public List<DCValue> getConstant() public List<DCValue> getConstant()
{ {
// Return the array // Return the array
return constant; return constant;
} }
/** /**
* Get the list of all values * Get the list of all values
* *
* @return the list of all values * @return the list of all values
*/ */
public List<DCValue> getComplete() public List<DCValue> getComplete()
{ {
// Return the array // Return the array
return complete; return complete;
} }
/** /**
* Get the list of new mapped Collections * Get the list of new mapped Collections
* *
* @return the list of new mapped collections * @return the list of new mapped collections
*/ */
public List<Collection> getNewMappedCollections() public List<Collection> getNewMappedCollections()
{ {
// Return the array // Return the array
return newMappedCollections; return newMappedCollections;
} }
/** /**
* Get the list of old mapped Collections * Get the list of old mapped Collections
* *
* @return the list of old mapped collections * @return the list of old mapped collections
*/ */
public List<Collection> getOldMappedCollections() public List<Collection> getOldMappedCollections()
{ {
// Return the array // Return the array
return oldMappedCollections; return oldMappedCollections;
} }
/** /**
* Get the old owning collection * Get the old owning collection
* *
* @return the old owning collection * @return the old owning collection
*/ */
public Collection getOldOwningCollection() public Collection getOldOwningCollection()
{ {
// Return the old owning collection // Return the old owning collection
return oldOwningCollection; return oldOwningCollection;
} }
/** /**
* Get the new owning collection * Get the new owning collection
* *
* @return the new owning collection * @return the new owning collection
*/ */
public Collection getNewOwningCollection() public Collection getNewOwningCollection()
{ {
// Return the new owning collection // Return the new owning collection
return newOwningCollection; return newOwningCollection;
} }
/** /**
* Does this change object represent a new item? * Does this change object represent a new item?
* *
* @return Whether or not this is for a new item * @return Whether or not this is for a new item
*/ */
public boolean isNewItem() public boolean isNewItem()
{ {
// Return the new item status // Return the new item status
return newItem; return newItem;
} }
/** /**
* Have any changes actually been recorded, or is this empty? * Have any changes actually been recorded, or is this empty?
* *
* @return Whether or not changes have been made * @return Whether or not changes have been made
*/ */
public boolean hasChanges() public boolean hasChanges()
{ {
return !empty; 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 * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.app.bulkedit; package org.dspace.app.bulkedit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
* Utility class to store a line from a CSV file * Utility class to store a line from a CSV file
* *
* @author Stuart Lewis * @author Stuart Lewis
*/ */
public class DSpaceCSVLine public class DSpaceCSVLine
{ {
/** The item id of the item represented by this line. -1 is for a new item */ /** The item id of the item represented by this line. -1 is for a new item */
private int id; private int id;
/** The elements in this line in a hashtable, keyed by the metadata type */ /** The elements in this line in a hashtable, keyed by the metadata type */
private Map<String, ArrayList> items; private Map<String, ArrayList> items;
/** /**
* Create a new CSV line * Create a new CSV line
* *
* @param id The item ID of the line * @param id The item ID of the line
*/ */
public DSpaceCSVLine(int itemId) public DSpaceCSVLine(int itemId)
{ {
// Store the ID + separator, and initialise the hashtable // Store the ID + separator, and initialise the hashtable
this.id = itemId; this.id = itemId;
items = new HashMap<String, ArrayList>(); items = new HashMap<String, ArrayList>();
} }
/** /**
* Create a new CSV line for a new item * Create a new CSV line for a new item
*/ */
public DSpaceCSVLine() public DSpaceCSVLine()
{ {
// Set the ID to be -1, and initialise the hashtable // Set the ID to be -1, and initialise the hashtable
this.id = -1; this.id = -1;
this.items = new HashMap<String, ArrayList>(); this.items = new HashMap<String, ArrayList>();
} }
/** /**
* Get the item ID that this line represents * Get the item ID that this line represents
* *
* @return The item ID * @return The item ID
*/ */
public int getID() public int getID()
{ {
// Return the ID // Return the ID
return id; return id;
} }
/** /**
* Add a new metadata value to this line * Add a new metadata value to this line
* *
* @param key The metadata key (e.g. dc.contributor.author) * @param key The metadata key (e.g. dc.contributor.author)
* @param value The metadata value * @param value The metadata value
*/ */
public void add(String key, String value) public void add(String key, String value)
{ {
// Create the array list if we need to // Create the array list if we need to
if (items.get(key) == null) if (items.get(key) == null)
{ {
items.put(key, new ArrayList<String>()); items.put(key, new ArrayList<String>());
} }
// Store the item if it is not null // Store the item if it is not null
if (value != null) if (value != null)
{ {
items.get(key).add(value); items.get(key).add(value);
} }
} }
/** /**
* Get all the values that match the given metadata key. Will be null if none exist. * Get all the values that match the given metadata key. Will be null if none exist.
* *
* @param key The metadata key * @param key The metadata key
* @return All the elements that match * @return All the elements that match
*/ */
public List<String> get(String key) public List<String> get(String key)
{ {
// Return any relevant values // Return any relevant values
return items.get(key); return items.get(key);
} }
/** /**
* Get all the metadata keys that are represented in this line * Get all the metadata keys that are represented in this line
* *
* @return An enumeration of all the keys * @return An enumeration of all the keys
*/ */
public Set<String> keys() public Set<String> keys()
{ {
// Return the keys // Return the keys
return items.keySet(); return items.keySet();
} }
/** /**
* Write this line out as a CSV formatted string, in the order given by the headings provided * 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 * @param headings The headings which define the order the elements must be presented in
* @return The CSV formatted String * @return The CSV formatted String
*/ */
protected String toCSV(List<String> headings) protected String toCSV(List<String> headings)
{ {
StringBuilder bits = new StringBuilder(); StringBuilder bits = new StringBuilder();
// Add the id // Add the id
bits.append("\"").append(id).append("\"").append(DSpaceCSV.fieldSeparator); bits.append("\"").append(id).append("\"").append(DSpaceCSV.fieldSeparator);
bits.append(valueToCSV(items.get("collection"))); bits.append(valueToCSV(items.get("collection")));
// Add the rest of the elements // Add the rest of the elements
for (String heading : headings) for (String heading : headings)
{ {
bits.append(DSpaceCSV.fieldSeparator); bits.append(DSpaceCSV.fieldSeparator);
List<String> values = items.get(heading); List<String> values = items.get(heading);
if (values != null && !"collection".equals(heading)) if (values != null && !"collection".equals(heading))
{ {
bits.append(valueToCSV(values)); bits.append(valueToCSV(values));
} }
} }
return bits.toString(); return bits.toString();
} }
/** /**
* Internal method to create a CSV formatted String joining a given set of elements * Internal method to create a CSV formatted String joining a given set of elements
* *
* @param values The values to create the string from * @param values The values to create the string from
* @return The line as a CSV formatted String * @return The line as a CSV formatted String
*/ */
protected String valueToCSV(List<String> values) protected String valueToCSV(List<String> values)
{ {
// Check there is some content // Check there is some content
if (values == null) if (values == null)
{ {
return ""; return "";
} }
// Get on with the work // Get on with the work
String s; String s;
if (values.size() == 1) if (values.size() == 1)
{ {
s = values.get(0); s = values.get(0);
} }
else else
{ {
// Concatenate any fields together // Concatenate any fields together
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
for (String value : values) for (String value : values)
{ {
if (str.length() > 0) if (str.length() > 0)
{ {
str.append(DSpaceCSV.valueSeparator); str.append(DSpaceCSV.valueSeparator);
} }
str.append(value); str.append(value);
} }
s = str.toString(); s = str.toString();
} }
// Replace internal quotes with two sets of quotes // Replace internal quotes with two sets of quotes
return "\"" + s.replaceAll("\"", "\"\"") + "\""; 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; int i = 0;
while(dcf.hasMoreTokens()) while(dcf.hasMoreTokens())
{ {
tokens[i] = dcf.nextToken().toLowerCase().trim(); tokens[i] = dcf.nextToken().trim();
i++; i++;
} }
String schema = tokens[0]; String schema = tokens[0];
@@ -908,7 +908,8 @@ public class Item extends DSpaceObject
return false; return false;
} }
} }
else if (!schema.equals(Item.ANY))
if (!schema.equals(Item.ANY))
{ {
if (dcv.schema != null && !dcv.schema.equals(schema)) 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 * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content; package org.dspace.content;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Formatter; import java.util.Formatter;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.license.FormattableArgument; import org.dspace.content.license.FormattableArgument;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
/** /**
* Utility class to manage generation and storing of the license text that the * Utility class to manage generation and storing of the license text that the
* submitter has to grant/granted for archiving the item * submitter has to grant/granted for archiving the item
* *
* @author bollini * @author bollini
* *
*/ */
public class LicenseUtils public class LicenseUtils
{ {
/** /**
* Return the text of the license that the user has granted/must grant * 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 * 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 * defined for the collection if any or the wide site configuration. In the
* license text the following substitution can be used. {0} the eperson * license text the following substitution can be used. {0} the eperson
* firstname<br> * firstname<br>
* {1} the eperson lastname<br> * {1} the eperson lastname<br>
* {2} the eperson email<br> * {2} the eperson email<br>
* {3} the current date<br> * {3} the current date<br>
* {4} the collection object that will be formatted using the appropriate * {4} the collection object that will be formatted using the appropriate
* LicenseArgumentFormatter plugin (if defined)<br> * LicenseArgumentFormatter plugin (if defined)<br>
* {5} the item object that will be formatted using the appropriate * {5} the item object that will be formatted using the appropriate
* LicenseArgumentFormatter plugin (if defined)<br> * LicenseArgumentFormatter plugin (if defined)<br>
* {6} the eperson object that will be formatted using the appropriate * {6} the eperson object that will be formatted using the appropriate
* LicenseArgumentFormatter plugin (if defined)<br> * LicenseArgumentFormatter plugin (if defined)<br>
* {x} any addition argument supplied wrapped in the * {x} any addition argument supplied wrapped in the
* LicenseArgumentFormatter based on his type (map key) * LicenseArgumentFormatter based on his type (map key)
* *
* @see LicenseArgumentFormatter * @see LicenseArgumentFormatter
* @param locale * @param locale
* @param collection * @param collection
* @param item * @param item
* @param eperson * @param eperson
* @param additionalInfo * @param additionalInfo
* @return the license text obtained substituting the provided argument in * @return the license text obtained substituting the provided argument in
* the license template * the license template
*/ */
public static String getLicenseText(Locale locale, Collection collection, public static String getLicenseText(Locale locale, Collection collection,
Item item, EPerson eperson, Map<String, Object> additionalInfo) Item item, EPerson eperson, Map<String, Object> additionalInfo)
{ {
Formatter formatter = new Formatter(locale); Formatter formatter = new Formatter(locale);
// EPerson firstname, lastname, email and the current date // EPerson firstname, lastname, email and the current date
// will be available as separate arguments to make more simple produce // will be available as separate arguments to make more simple produce
// "tradition" text license // "tradition" text license
// collection, item and eperson object will be also available // collection, item and eperson object will be also available
int numArgs = 7 + (additionalInfo != null ? additionalInfo.size() : 0); int numArgs = 7 + (additionalInfo != null ? additionalInfo.size() : 0);
Object[] args = new Object[numArgs]; Object[] args = new Object[numArgs];
args[0] = eperson.getFirstName(); args[0] = eperson.getFirstName();
args[1] = eperson.getLastName(); args[1] = eperson.getLastName();
args[2] = eperson.getEmail(); args[2] = eperson.getEmail();
args[3] = new java.util.Date(); args[3] = new java.util.Date();
args[4] = new FormattableArgument("collection", collection); args[4] = new FormattableArgument("collection", collection);
args[5] = new FormattableArgument("item", item); args[5] = new FormattableArgument("item", item);
args[6] = new FormattableArgument("eperson", eperson); args[6] = new FormattableArgument("eperson", eperson);
if (additionalInfo != null) if (additionalInfo != null)
{ {
int i = 7; // Start is next index after previous args int i = 7; // Start is next index after previous args
for (Map.Entry<String, Object> info : additionalInfo.entrySet()) for (Map.Entry<String, Object> info : additionalInfo.entrySet())
{ {
args[i] = new FormattableArgument(info.getKey(), info.getValue()); args[i] = new FormattableArgument(info.getKey(), info.getValue());
i++; i++;
} }
} }
String licenseTemplate = collection.getLicense(); String licenseTemplate = collection.getLicense();
return formatter.format(licenseTemplate, args).toString(); return formatter.format(licenseTemplate, args).toString();
} }
/** /**
* Utility method if no additional arguments has need to be supplied to the * Utility method if no additional arguments has need to be supplied to the
* license template. (i.e. call the full getLicenseText supplying * license template. (i.e. call the full getLicenseText supplying
* <code>null</code> for the additionalInfo argument) * <code>null</code> for the additionalInfo argument)
* *
* @param locale * @param locale
* @param collection * @param collection
* @param item * @param item
* @param eperson * @param eperson
* @return * @return
*/ */
public static String getLicenseText(Locale locale, Collection collection, public static String getLicenseText(Locale locale, Collection collection,
Item item, EPerson eperson) Item item, EPerson eperson)
{ {
return getLicenseText(locale, collection, item, eperson, null); return getLicenseText(locale, collection, item, eperson, null);
} }
/** /**
* Store a copy of the license a user granted in the item. * Store a copy of the license a user granted in the item.
* *
* @param context * @param context
* the dspace context * the dspace context
* @param item * @param item
* the item object of the license * the item object of the license
* @param licenseText * @param licenseText
* the license the user granted * the license the user granted
* @throws SQLException * @throws SQLException
* @throws IOException * @throws IOException
* @throws AuthorizeException * @throws AuthorizeException
*/ */
public static void grantLicense(Context context, Item item, public static void grantLicense(Context context, Item item,
String licenseText) throws SQLException, IOException, String licenseText) throws SQLException, IOException,
AuthorizeException AuthorizeException
{ {
// Put together text to store // Put together text to store
// String licenseText = "License granted by " + eperson.getFullName() // String licenseText = "License granted by " + eperson.getFullName()
// + " (" + eperson.getEmail() + ") on " // + " (" + eperson.getEmail() + ") on "
// + DCDate.getCurrent().toString() + " (GMT):\n\n" + license; // + DCDate.getCurrent().toString() + " (GMT):\n\n" + license;
// Store text as a bitstream // Store text as a bitstream
byte[] licenseBytes = licenseText.getBytes(); byte[] licenseBytes = licenseText.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(licenseBytes); ByteArrayInputStream bais = new ByteArrayInputStream(licenseBytes);
Bitstream b = item.createSingleBitstream(bais, "LICENSE"); Bitstream b = item.createSingleBitstream(bais, "LICENSE");
// Now set the format and name of the bitstream // Now set the format and name of the bitstream
b.setName("license.txt"); b.setName("license.txt");
b.setSource("Written by org.dspace.content.LicenseUtils"); b.setSource("Written by org.dspace.content.LicenseUtils");
// Find the License format // Find the License format
BitstreamFormat bf = BitstreamFormat.findByShortDescription(context, BitstreamFormat bf = BitstreamFormat.findByShortDescription(context,
"License"); "License");
b.setFormat(bf); b.setFormat(bf);
b.update(); b.update();
} }
} }

View File

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

View File

@@ -362,6 +362,34 @@ public class WorkspaceItem implements InProgressSubmission
return wsItems.toArray(new WorkspaceItem[wsItems.size()]); 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 * 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, * defaultSelected index in the Choices instance to the choice, if any,
* that matches the value. * that matches the value.
* *
* @param field being matched for
* @param text user's value to match * @param text user's value to match
* @param collection database ID of Collection for context (owner of Item) * @param collection database ID of Collection for context (owner of Item)
* @param start choice at which to start, 0 is first. * @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 * @param locale explicit localization key if available, or null
* @return a Choices object (never 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 * 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 * This call is typically used in non-interactive metadata ingest
* where there is no interactive agent to choose from among options. * where there is no interactive agent to choose from among options.
* *
* @param field being matched for
* @param text user's value to match * @param text user's value to match
* @param collection database ID of Collection for context (owner of Item) * @param collection database ID of Collection for context (owner of Item)
* @param locale explicit localization key if available, or null * @param locale explicit localization key if available, or null
* @return a Choices object (never null) with 1 or 0 values. * @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) * 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 * This may get called many times while populating a Web page so it should
* be implemented as efficiently as possible. * be implemented as efficiently as possible.
* *
* @param field being matched for
* @param key authority key known to this authority. * @param key authority key known to this authority.
* @param locale explicit localization key if available, or null * @param locale explicit localization key if available, or null
* @return descriptive label - should always return something, never 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 * Wrapper that calls getMatches method of the plugin corresponding to
* the metadata field defined by schema,element,qualifier. * 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 schema schema of metadata field
* @param element element of metadata field * @param element element of metadata field
* @param qualifier qualifier 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 * Wrapper calls getMatches method of the plugin corresponding to
* the metadata field defined by single field key. * 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 fieldKey single string identifying metadata field
* @param query user's value to match * @param query user's value to match
* @param collection database ID of Collection for context (owner of Item) * @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 "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 * Wrapper that calls getBestMatch method of the plugin corresponding to
* the metadata field defined by single field key. * 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 fieldKey single string identifying metadata field
* @param query user's value to match * @param query user's value to match
* @param collection database ID of Collection for context (owner of Item) * @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 "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 + "\"."); 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(); init();
@@ -134,7 +134,7 @@ public class DCInputAuthority extends SelfNamedPlugin implements ChoiceAuthority
return new Choices(v, 0, v.length, Choices.CF_AMBIGUOUS, false, dflt); 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(); init();
for (int i = 0; i < values.length; ++i) 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); return new Choices(Choices.CF_NOTFOUND);
} }
public String getLabel(String key, String locale) public String getLabel(String field, String key, String locale)
{ {
init(); init();
return labels[Integer.parseInt(key)]; 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(); init();
log.debug("Getting matches for '" + text + "'"); 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); 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(); init();
log.debug("Getting best match for '" + text + "'"); 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(); init();
String xpathExpression = String.format(idTemplate, key); String xpathExpression = String.format(idTemplate, key);
@@ -222,4 +222,4 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Choic
return(""); return("");
} }
} }
} }

View File

@@ -83,16 +83,16 @@ public class LCNameAuthority implements ChoiceAuthority
} }
// punt! this is a poor implementation.. // 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 * Match a proposed value against name authority records
* Value is assumed to be in "Lastname, Firstname" format. * 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); Choices result = queryPerson(text, start, limit);
if (result == null) 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 // 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 // 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; return key;
} }

View File

@@ -52,4 +52,8 @@ public class SHERPARoMEOJournalTitle extends SHERPARoMEOProtocol
return result; 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 // 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 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 // XXX FIXME just punt, returning value, never got around to
// implementing a reverse query. // implementing a reverse query.
public String getLabel(String key, String locale) public String getLabel(String field, String key, String locale)
{ {
return key; return key;
} }

View File

@@ -53,4 +53,9 @@ public class SHERPARoMEOPublisher extends SHERPARoMEOProtocol
} }
return result; 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" "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; int dflt = -1;
Choice v[] = new Choice[values.length]; 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); 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) for (int i = 0; i < values.length; ++i)
{ {
@@ -62,7 +62,7 @@ public class SampleAuthority implements ChoiceAuthority
return new Choices(Choices.CF_NOTFOUND); 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)]; return labels[Integer.parseInt(key)];
} }

View File

@@ -1,174 +1,174 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.sql.SQLException; import java.sql.SQLException;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.jdom.Element; import org.jdom.Element;
import org.jdom.Namespace; import org.jdom.Namespace;
/** /**
* Crosswalk descriptive metadata to and from DIM (DSpace Intermediate * Crosswalk descriptive metadata to and from DIM (DSpace Intermediate
* Metadata) format, strictly for the purpose of including a precise and * 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 * 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 * intended to be used outside of DSpace, it is admirably suited to
* describing the exact state of the descriptive MD stored in the RDBMS. * 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 * 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 * "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 * the state of an object exactly, DIM is the preferred format for
* recording its descriptive MD. * recording its descriptive MD.
* <p> * <p>
* In order to allow external applications to make sense of DSpace AIPs for * In order to allow external applications to make sense of DSpace AIPs for
* preservation purposes, we recommend adding a parallel descriptive * preservation purposes, we recommend adding a parallel descriptive
* metadata section in one of the preferred standard formats such as MODS * metadata section in one of the preferred standard formats such as MODS
* as well as the DIM. * as well as the DIM.
* *
* @author Larry Stone * @author Larry Stone
* @version $Revision: 1.2 $ * @version $Revision: 1.2 $
*/ */
public class AIPDIMCrosswalk public class AIPDIMCrosswalk
implements DisseminationCrosswalk, IngestionCrosswalk implements DisseminationCrosswalk, IngestionCrosswalk
{ {
/** /**
* Get XML namespaces of the elements this crosswalk may return. * Get XML namespaces of the elements this crosswalk may return.
* Returns the XML namespaces (as JDOM objects) of the root element. * Returns the XML namespaces (as JDOM objects) of the root element.
* *
* @return array of namespaces, which may be empty. * @return array of namespaces, which may be empty.
*/ */
public Namespace[] getNamespaces() public Namespace[] getNamespaces()
{ {
Namespace result[] = new Namespace[1]; Namespace result[] = new Namespace[1];
result[0] = XSLTCrosswalk.DIM_NS; result[0] = XSLTCrosswalk.DIM_NS;
return result; return result;
} }
/** /**
* Get the XML Schema location(s) of the target metadata format. * Get the XML Schema location(s) of the target metadata format.
* Returns the string value of the <code>xsi:schemaLocation</code> * Returns the string value of the <code>xsi:schemaLocation</code>
* attribute that should be applied to the generated XML. * attribute that should be applied to the generated XML.
* <p> * <p>
* It may return the empty string if no schema is known, but crosswalk * It may return the empty string if no schema is known, but crosswalk
* authors are strongly encouraged to implement this call so their output * authors are strongly encouraged to implement this call so their output
* XML can be validated correctly. * XML can be validated correctly.
* @return SchemaLocation string, including URI namespace, followed by * @return SchemaLocation string, including URI namespace, followed by
* whitespace and URI of XML schema document, or empty string if unknown. * whitespace and URI of XML schema document, or empty string if unknown.
*/ */
public String getSchemaLocation() public String getSchemaLocation()
{ {
return ""; return "";
} }
/** /**
* Predicate: Can this disseminator crosswalk the given object. * Predicate: Can this disseminator crosswalk the given object.
* Needed by OAI-PMH server implementation. * Needed by OAI-PMH server implementation.
* *
* @param dso dspace object, e.g. an <code>Item</code>. * @param dso dspace object, e.g. an <code>Item</code>.
* @return true when disseminator is capable of producing metadata. * @return true when disseminator is capable of producing metadata.
*/ */
public boolean canDisseminate(DSpaceObject dso) public boolean canDisseminate(DSpaceObject dso)
{ {
return true; return true;
} }
/** /**
* Predicate: Does this disseminator prefer to return a list of Elements, * Predicate: Does this disseminator prefer to return a list of Elements,
* rather than a single root Element? * rather than a single root Element?
* <p> * <p>
* Some metadata formats have an XML schema without a root element, * Some metadata formats have an XML schema without a root element,
* for example, the Dublin Core and Qualified Dublin Core formats. * for example, the Dublin Core and Qualified Dublin Core formats.
* This would be <code>true</code> for a crosswalk into QDC, since * 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 * 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 * to produce would have to be part of a nonstandard schema. In
* most cases your implementation will want to return * most cases your implementation will want to return
* <code>false</code> * <code>false</code>
* *
* @return true when disseminator prefers you call disseminateList(). * @return true when disseminator prefers you call disseminateList().
*/ */
public boolean preferList() public boolean preferList()
{ {
return false; return false;
} }
/** /**
* Execute crosswalk, returning List of XML elements. * Execute crosswalk, returning List of XML elements.
* Returns a <code>List</code> of JDOM <code>Element</code> objects representing * Returns a <code>List</code> of JDOM <code>Element</code> objects representing
* the XML produced by the crosswalk. This is typically called when * 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 * a list of fields is desired, e.g. for embedding in a METS document
* <code>xmlData</code> field. * <code>xmlData</code> field.
* <p> * <p>
* When there are no results, an * When there are no results, an
* empty list is returned, but never <code>null</code>. * empty list is returned, but never <code>null</code>.
* *
* @param dso the DSpace Object whose metadata to export. * @param dso the DSpace Object whose metadata to export.
* @return results of crosswalk as list of XML elements. * @return results of crosswalk as list of XML elements.
* *
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself. * @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object. * @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
* @throws IOException I/O failure in services this calls * @throws IOException I/O failure in services this calls
* @throws SQLException Database failure in services this calls * @throws SQLException Database failure in services this calls
* @throws AuthorizeException current user not authorized for this operation. * @throws AuthorizeException current user not authorized for this operation.
*/ */
public List<Element> disseminateList(DSpaceObject dso) public List<Element> disseminateList(DSpaceObject dso)
throws CrosswalkException, IOException, SQLException, throws CrosswalkException, IOException, SQLException,
AuthorizeException AuthorizeException
{ {
Element dim = disseminateElement(dso); Element dim = disseminateElement(dso);
return dim.getChildren(); return dim.getChildren();
} }
/** /**
* Execute crosswalk, returning one XML root element as * Execute crosswalk, returning one XML root element as
* a JDOM <code>Element</code> object. * a JDOM <code>Element</code> object.
* This is typically the root element of a document. * This is typically the root element of a document.
* <p> * <p>
* *
* @param dso the DSpace Object whose metadata to export. * @param dso the DSpace Object whose metadata to export.
* @return root Element of the target metadata, never <code>null</code> * @return root Element of the target metadata, never <code>null</code>
* *
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself. * @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object. * @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
* @throws IOException I/O failure in services this calls * @throws IOException I/O failure in services this calls
* @throws SQLException Database failure in services this calls * @throws SQLException Database failure in services this calls
* @throws AuthorizeException current user not authorized for this operation. * @throws AuthorizeException current user not authorized for this operation.
*/ */
public Element disseminateElement(DSpaceObject dso) public Element disseminateElement(DSpaceObject dso)
throws CrosswalkException, IOException, SQLException, throws CrosswalkException, IOException, SQLException,
AuthorizeException AuthorizeException
{ {
return XSLTDisseminationCrosswalk.createDIM(dso); return XSLTDisseminationCrosswalk.createDIM(dso);
} }
/** /**
* Ingest a whole document. Build Document object around root element, * Ingest a whole document. Build Document object around root element,
* and feed that to the transformation, since it may get handled * and feed that to the transformation, since it may get handled
* differently than a List of metadata elements. * differently than a List of metadata elements.
*/ */
public void ingest(Context context, DSpaceObject dso, Element root) public void ingest(Context context, DSpaceObject dso, Element root)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
ingest(context, dso, root.getChildren()); ingest(context, dso, root.getChildren());
} }
/** /**
* Fields correspond directly to Item.addMetadata() calls so * Fields correspond directly to Item.addMetadata() calls so
* they are simply executed. * they are simply executed.
*/ */
public void ingest(Context context, DSpaceObject dso, List<Element> dimList) public void ingest(Context context, DSpaceObject dso, List<Element> dimList)
throws CrosswalkException, throws CrosswalkException,
IOException, SQLException, AuthorizeException IOException, SQLException, AuthorizeException
{ {
XSLTIngestionCrosswalk.ingestDIM(context, dso, dimList); XSLTIngestionCrosswalk.ingestDIM(context, dso, dimList);
} }
} }

View File

@@ -1,69 +1,69 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.Utils; import org.dspace.core.Utils;
import org.dspace.license.CreativeCommons; import org.dspace.license.CreativeCommons;
/** /**
* Export the item's Creative Commons license, RDF form. * Export the item's Creative Commons license, RDF form.
* *
* @author Larry Stone * @author Larry Stone
* @version $Revision: 1.0 $ * @version $Revision: 1.0 $
*/ */
public class CreativeCommonsRDFStreamDisseminationCrosswalk public class CreativeCommonsRDFStreamDisseminationCrosswalk
implements StreamDisseminationCrosswalk implements StreamDisseminationCrosswalk
{ {
/** log4j logger */ /** log4j logger */
private static Logger log = Logger.getLogger(CreativeCommonsRDFStreamDisseminationCrosswalk.class); private static Logger log = Logger.getLogger(CreativeCommonsRDFStreamDisseminationCrosswalk.class);
public boolean canDisseminate(Context context, DSpaceObject dso) public boolean canDisseminate(Context context, DSpaceObject dso)
{ {
try try
{ {
return dso.getType() == Constants.ITEM && return dso.getType() == Constants.ITEM &&
CreativeCommons.getLicenseRdfBitstream((Item)dso) != null; CreativeCommons.getLicenseRdfBitstream((Item)dso) != null;
} }
catch (Exception e) catch (Exception e)
{ {
log.error("Failed getting CC license", e); log.error("Failed getting CC license", e);
return false; return false;
} }
} }
public void disseminate(Context context, DSpaceObject dso, OutputStream out) public void disseminate(Context context, DSpaceObject dso, OutputStream out)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
if (dso.getType() == Constants.ITEM) if (dso.getType() == Constants.ITEM)
{ {
Bitstream cc = CreativeCommons.getLicenseRdfBitstream((Item)dso); Bitstream cc = CreativeCommons.getLicenseRdfBitstream((Item)dso);
if (cc != null) if (cc != null)
{ {
Utils.copy(cc.retrieve(), out); Utils.copy(cc.retrieve(), out);
out.close(); out.close();
} }
} }
} }
public String getMIMEType() public String getMIMEType()
{ {
return "text/xml"; return "text/xml";
} }
} }

View File

@@ -1,62 +1,62 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.license.CreativeCommons; import org.dspace.license.CreativeCommons;
/** /**
* Ingest a Creative Commons license, RDF form. * Ingest a Creative Commons license, RDF form.
* <p> * <p>
* Note that this is NOT needed when ingesting a DSpace AIP, since the * 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; * CC license is stored as a Bitstream (or two) in a dedicated Bundle;
* the normal apparatus of ingestig the AIP will restore that Bitstream * the normal apparatus of ingestig the AIP will restore that Bitstream
* with its proper name and thus the presence of the CC license. * with its proper name and thus the presence of the CC license.
* <p> * <p>
* This crosswalk should only be used when ingesting other kinds of SIPs. * This crosswalk should only be used when ingesting other kinds of SIPs.
* *
* @author Larry Stone * @author Larry Stone
* @version $Revision: 1.0 $ * @version $Revision: 1.0 $
*/ */
public class CreativeCommonsRDFStreamIngestionCrosswalk public class CreativeCommonsRDFStreamIngestionCrosswalk
implements StreamIngestionCrosswalk implements StreamIngestionCrosswalk
{ {
/** log4j logger */ /** log4j logger */
private static Logger log = Logger.getLogger(CreativeCommonsRDFStreamIngestionCrosswalk.class); private static Logger log = Logger.getLogger(CreativeCommonsRDFStreamIngestionCrosswalk.class);
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType) public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
// If package includes a Creative Commons license, add that: // If package includes a Creative Commons license, add that:
if (dso.getType() == Constants.ITEM) if (dso.getType() == Constants.ITEM)
{ {
if (log.isDebugEnabled()) if (log.isDebugEnabled())
{ {
log.debug("Reading a Creative Commons license, MIMEtype=" + MIMEType); log.debug("Reading a Creative Commons license, MIMEtype=" + MIMEType);
} }
CreativeCommons.setLicense(context, (Item)dso, in, MIMEType); CreativeCommons.setLicense(context, (Item)dso, in, MIMEType);
} }
} }
public String getMIMEType() public String getMIMEType()
{ {
return "text/rdf"; return "text/rdf";
} }
} }

View File

@@ -1,69 +1,69 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.Utils; import org.dspace.core.Utils;
import org.dspace.license.CreativeCommons; import org.dspace.license.CreativeCommons;
/** /**
* Export the object's Creative Commons license, text form. * Export the object's Creative Commons license, text form.
* *
* @author Larry Stone * @author Larry Stone
* @version $Revision: 1.0 $ * @version $Revision: 1.0 $
*/ */
public class CreativeCommonsTextStreamDisseminationCrosswalk public class CreativeCommonsTextStreamDisseminationCrosswalk
implements StreamDisseminationCrosswalk implements StreamDisseminationCrosswalk
{ {
/** log4j logger */ /** log4j logger */
private static Logger log = Logger.getLogger(CreativeCommonsTextStreamDisseminationCrosswalk.class); private static Logger log = Logger.getLogger(CreativeCommonsTextStreamDisseminationCrosswalk.class);
public boolean canDisseminate(Context context, DSpaceObject dso) public boolean canDisseminate(Context context, DSpaceObject dso)
{ {
try try
{ {
return dso.getType() == Constants.ITEM && return dso.getType() == Constants.ITEM &&
CreativeCommons.getLicenseTextBitstream((Item)dso) != null; CreativeCommons.getLicenseTextBitstream((Item)dso) != null;
} }
catch (Exception e) catch (Exception e)
{ {
log.error("Failed getting CC license", e); log.error("Failed getting CC license", e);
return false; return false;
} }
} }
public void disseminate(Context context, DSpaceObject dso, OutputStream out) public void disseminate(Context context, DSpaceObject dso, OutputStream out)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
if (dso.getType() == Constants.ITEM) if (dso.getType() == Constants.ITEM)
{ {
Bitstream cc = CreativeCommons.getLicenseTextBitstream((Item)dso); Bitstream cc = CreativeCommons.getLicenseTextBitstream((Item)dso);
if (cc != null) if (cc != null)
{ {
Utils.copy(cc.retrieve(), out); Utils.copy(cc.retrieve(), out);
out.close(); out.close();
} }
} }
} }
public String getMIMEType() public String getMIMEType()
{ {
return "text/plain"; return "text/plain";
} }
} }

View File

@@ -1,21 +1,21 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
public interface IConverter public interface IConverter
{ {
/** /**
* Get an alternative format for the input string. Useful examples are * 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. * conversion from a metadata language value in ISO-639-3 to ISO-639-1, etc.
* *
* @param value * @param value
* the input string to convert * the input string to convert
* @return the converted string returned by the "conversion algorithm" * @return the converted string returned by the "conversion algorithm"
*/ */
public String makeConversion(String value); public String makeConversion(String value);
} }

View File

@@ -1,70 +1,70 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.packager.PackageUtils; import org.dspace.content.packager.PackageUtils;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.Utils; import org.dspace.core.Utils;
/** /**
* Export the object's DSpace deposit license. * Export the object's DSpace deposit license.
* *
* @author Larry Stone * @author Larry Stone
* @version $Revision: 1.0 $ * @version $Revision: 1.0 $
*/ */
public class LicenseStreamDisseminationCrosswalk public class LicenseStreamDisseminationCrosswalk
implements StreamDisseminationCrosswalk implements StreamDisseminationCrosswalk
{ {
/** log4j logger */ /** log4j logger */
private static Logger log = Logger.getLogger(LicenseStreamDisseminationCrosswalk.class); private static Logger log = Logger.getLogger(LicenseStreamDisseminationCrosswalk.class);
public boolean canDisseminate(Context context, DSpaceObject dso) public boolean canDisseminate(Context context, DSpaceObject dso)
{ {
try try
{ {
return dso.getType() == Constants.ITEM && return dso.getType() == Constants.ITEM &&
PackageUtils.findDepositLicense(context, (Item)dso) != null; PackageUtils.findDepositLicense(context, (Item)dso) != null;
} }
catch (Exception e) catch (Exception e)
{ {
log.error("Failed getting Deposit license", e); log.error("Failed getting Deposit license", e);
return false; return false;
} }
} }
public void disseminate(Context context, DSpaceObject dso, OutputStream out) public void disseminate(Context context, DSpaceObject dso, OutputStream out)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
if (dso.getType() == Constants.ITEM) if (dso.getType() == Constants.ITEM)
{ {
Bitstream licenseBs = PackageUtils.findDepositLicense(context, (Item)dso); Bitstream licenseBs = PackageUtils.findDepositLicense(context, (Item)dso);
if (licenseBs != null) if (licenseBs != null)
{ {
Utils.copy(licenseBs.retrieve(), out); Utils.copy(licenseBs.retrieve(), out);
out.close(); out.close();
} }
} }
} }
public String getMIMEType() public String getMIMEType()
{ {
return "text/plain"; return "text/plain";
} }
} }

View File

@@ -1,66 +1,66 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.packager.PackageUtils; import org.dspace.content.packager.PackageUtils;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.Utils; import org.dspace.core.Utils;
/** /**
* Accept a DSpace deposit license. * Accept a DSpace deposit license.
* <p> * <p>
* Note that this is NOT needed when ingesting a DSpace AIP, since the * 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; * deposit license is stored as a Bitstream (or two) in a dedicated Bundle;
* the normal apparatus of ingestig the AIP will restore that Bitstream * the normal apparatus of ingestig the AIP will restore that Bitstream
* with its proper name and thus the presence of the deposit license. * with its proper name and thus the presence of the deposit license.
* <p> * <p>
* This crosswalk should only be used when ingesting other kinds of SIPs. * This crosswalk should only be used when ingesting other kinds of SIPs.
* *
* @author Larry Stone * @author Larry Stone
* @version $Revision: 1.0 $ * @version $Revision: 1.0 $
*/ */
public class LicenseStreamIngestionCrosswalk public class LicenseStreamIngestionCrosswalk
implements StreamIngestionCrosswalk implements StreamIngestionCrosswalk
{ {
/** log4j logger */ /** log4j logger */
private static Logger log = Logger.getLogger(LicenseStreamIngestionCrosswalk.class); private static Logger log = Logger.getLogger(LicenseStreamIngestionCrosswalk.class);
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType) public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
// If package includes a Creative Commons license, add that: // If package includes a Creative Commons license, add that:
if (dso.getType() == Constants.ITEM) if (dso.getType() == Constants.ITEM)
{ {
if (log.isDebugEnabled()) if (log.isDebugEnabled())
{ {
log.debug("Reading a DSpace Deposit license, MIMEtype=" + MIMEType); log.debug("Reading a DSpace Deposit license, MIMEtype=" + MIMEType);
} }
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
Utils.copy(in, baos); Utils.copy(in, baos);
PackageUtils.addDepositLicense(context, baos.toString(), PackageUtils.addDepositLicense(context, baos.toString(),
(Item)dso, null); (Item)dso, null);
} }
} }
public String getMIMEType() public String getMIMEType()
{ {
return "text/plain"; return "text/plain";
} }
} }

View File

@@ -1,43 +1,43 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.core.Context; import org.dspace.core.Context;
/** /**
* A crosswalk to ignore and dispose of the ingested material. * A crosswalk to ignore and dispose of the ingested material.
* <p> * <p>
* Specify this crosswalk in the mapping of e.g. METS metadata field * Specify this crosswalk in the mapping of e.g. METS metadata field
* types to crosswalks when you wish to ignore a redundant or unknown * types to crosswalks when you wish to ignore a redundant or unknown
* type of metadata. For example, when ingesting a DSpace AIP with an * type of metadata. For example, when ingesting a DSpace AIP with an
* AIP ingester, it is best to ignore the rightsMD fields since they * AIP ingester, it is best to ignore the rightsMD fields since they
* are already going to be ingested as member bitstreams anyway. * are already going to be ingested as member bitstreams anyway.
* *
* @author Larry Stone * @author Larry Stone
* @version $Revision: 1.0 $ * @version $Revision: 1.0 $
*/ */
public class NullStreamIngestionCrosswalk public class NullStreamIngestionCrosswalk
implements StreamIngestionCrosswalk implements StreamIngestionCrosswalk
{ {
public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType) public void ingest(Context context, DSpaceObject dso, InputStream in, String MIMEType)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
in.close(); in.close();
} }
public String getMIMEType() public String getMIMEType()
{ {
return "text/plain"; return "text/plain";
} }
} }

View File

@@ -1,342 +1,342 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.crosswalk; package org.dspace.content.crosswalk;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.packager.PackageDisseminator; import org.dspace.content.packager.PackageDisseminator;
import org.dspace.content.packager.PackageException; import org.dspace.content.packager.PackageException;
import org.dspace.content.packager.PackageIngester; import org.dspace.content.packager.PackageIngester;
import org.dspace.content.packager.PackageParameters; import org.dspace.content.packager.PackageParameters;
import org.dspace.content.packager.RoleDisseminator; import org.dspace.content.packager.RoleDisseminator;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.PluginManager; import org.dspace.core.PluginManager;
import org.jdom.Document; import org.jdom.Document;
import org.jdom.Element; import org.jdom.Element;
import org.jdom.JDOMException; import org.jdom.JDOMException;
import org.jdom.Namespace; import org.jdom.Namespace;
import org.jdom.input.SAXBuilder; import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter; import org.jdom.output.XMLOutputter;
/** /**
* Role Crosswalk * Role Crosswalk
* <p> * <p>
* Translate between DSpace Group & EPeople definitions and a DSpace-specific * Translate between DSpace Group & EPeople definitions and a DSpace-specific
* XML export format (generated by the RoleDisseminator). This is primarily * XML export format (generated by the RoleDisseminator). This is primarily
* used for AIPs, but may be used by other Packagers as necessary. * used for AIPs, but may be used by other Packagers as necessary.
* <p> * <p>
* This crosswalk allows you to export DSpace Groups & EPeople to this XML * 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 * 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. * in order to restore DSpace Groups and EPeople defined within it.
* <p> * <p>
* This is just wrappers; the real work is done in RoleDisseminator and * This is just wrappers; the real work is done in RoleDisseminator and
* RoleIngester. * RoleIngester.
* *
* @author mwood * @author mwood
* @author Tim Donohue * @author Tim Donohue
* @see org.dspace.content.packager.RoleDisseminator * @see org.dspace.content.packager.RoleDisseminator
* @see org.dspace.content.packager.RoleIngester * @see org.dspace.content.packager.RoleIngester
* @see AbstractPackagerWrappingCrosswalk * @see AbstractPackagerWrappingCrosswalk
* @see IngestionCrosswalk * @see IngestionCrosswalk
* @see DisseminationCrosswalk * @see DisseminationCrosswalk
*/ */
public class RoleCrosswalk public class RoleCrosswalk
extends AbstractPackagerWrappingCrosswalk extends AbstractPackagerWrappingCrosswalk
implements IngestionCrosswalk, DisseminationCrosswalk implements IngestionCrosswalk, DisseminationCrosswalk
{ {
// Plugin Name of DSPACE-ROLES packager to use for ingest/dissemination // 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) // (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"; private static final String ROLE_PACKAGER_PLUGIN = "DSPACE-ROLES";
// ---- Dissemination Methods ----------- // ---- Dissemination Methods -----------
/** /**
* Get XML namespaces of the elements this crosswalk may return. * Get XML namespaces of the elements this crosswalk may return.
* Returns the XML namespaces (as JDOM objects) of the root element. * Returns the XML namespaces (as JDOM objects) of the root element.
* *
* @return array of namespaces, which may be empty. * @return array of namespaces, which may be empty.
*/ */
@Override @Override
public Namespace[] getNamespaces() public Namespace[] getNamespaces()
{ {
Namespace result[] = new Namespace[1]; Namespace result[] = new Namespace[1];
result[0] = RoleDisseminator.DSROLES_NS; result[0] = RoleDisseminator.DSROLES_NS;
return result; return result;
} }
/** /**
* Get the XML Schema location(s) of the target metadata format. * Get the XML Schema location(s) of the target metadata format.
* Returns the string value of the <code>xsi:schemaLocation</code> * Returns the string value of the <code>xsi:schemaLocation</code>
* attribute that should be applied to the generated XML. * attribute that should be applied to the generated XML.
* <p> * <p>
* It may return the empty string if no schema is known, but crosswalk * It may return the empty string if no schema is known, but crosswalk
* authors are strongly encouraged to implement this call so their output * authors are strongly encouraged to implement this call so their output
* XML can be validated correctly. * XML can be validated correctly.
* @return SchemaLocation string, including URI namespace, followed by * @return SchemaLocation string, including URI namespace, followed by
* whitespace and URI of XML schema document, or empty string if unknown. * whitespace and URI of XML schema document, or empty string if unknown.
*/ */
@Override @Override
public String getSchemaLocation() public String getSchemaLocation()
{ {
return ""; return "";
} }
/** /**
* Predicate: Can this disseminator crosswalk the given object. * Predicate: Can this disseminator crosswalk the given object.
* *
* @param dso dspace object, e.g. an <code>Item</code>. * @param dso dspace object, e.g. an <code>Item</code>.
* @return true when disseminator is capable of producing metadata. * @return true when disseminator is capable of producing metadata.
*/ */
@Override @Override
public boolean canDisseminate(DSpaceObject dso) public boolean canDisseminate(DSpaceObject dso)
{ {
//We can only disseminate SITE, COMMUNITY or COLLECTION objects, //We can only disseminate SITE, COMMUNITY or COLLECTION objects,
//as Groups are only associated with those objects. //as Groups are only associated with those objects.
return (dso.getType() == Constants.SITE || return (dso.getType() == Constants.SITE ||
dso.getType() == Constants.COMMUNITY || dso.getType() == Constants.COMMUNITY ||
dso.getType() == Constants.COLLECTION); dso.getType() == Constants.COLLECTION);
} }
/** /**
* Predicate: Does this disseminator prefer to return a list of Elements, * Predicate: Does this disseminator prefer to return a list of Elements,
* rather than a single root Element? * rather than a single root Element?
* *
* @return true when disseminator prefers you call disseminateList(). * @return true when disseminator prefers you call disseminateList().
*/ */
@Override @Override
public boolean preferList() public boolean preferList()
{ {
//We prefer disseminators call 'disseminateElement()' instead of 'disseminateList()' //We prefer disseminators call 'disseminateElement()' instead of 'disseminateList()'
return false; return false;
} }
/** /**
* Execute crosswalk, returning List of XML elements. * Execute crosswalk, returning List of XML elements.
* Returns a <code>List</code> of JDOM <code>Element</code> objects representing * Returns a <code>List</code> of JDOM <code>Element</code> objects representing
* the XML produced by the crosswalk. This is typically called when * 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 * a list of fields is desired, e.g. for embedding in a METS document
* <code>xmlData</code> field. * <code>xmlData</code> field.
* <p> * <p>
* When there are no results, an * When there are no results, an
* empty list is returned, but never <code>null</code>. * empty list is returned, but never <code>null</code>.
* *
* @param dso the DSpace Object whose metadata to export. * @param dso the DSpace Object whose metadata to export.
* @return results of crosswalk as list of XML elements. * @return results of crosswalk as list of XML elements.
* *
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself. * @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object. * @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
* @throws IOException I/O failure in services this calls * @throws IOException I/O failure in services this calls
* @throws SQLException Database failure in services this calls * @throws SQLException Database failure in services this calls
* @throws AuthorizeException current user not authorized for this operation. * @throws AuthorizeException current user not authorized for this operation.
*/ */
@Override @Override
public List<Element> disseminateList(DSpaceObject dso) public List<Element> disseminateList(DSpaceObject dso)
throws CrosswalkException, IOException, SQLException, throws CrosswalkException, IOException, SQLException,
AuthorizeException AuthorizeException
{ {
Element dim = disseminateElement(dso); Element dim = disseminateElement(dso);
return dim.getChildren(); return dim.getChildren();
} }
/** /**
* Execute crosswalk, returning one XML root element as * Execute crosswalk, returning one XML root element as
* a JDOM <code>Element</code> object. * a JDOM <code>Element</code> object.
* This is typically the root element of a document. * This is typically the root element of a document.
* <p> * <p>
* *
* @param dso the DSpace Object whose metadata to export. * @param dso the DSpace Object whose metadata to export.
* @return root Element of the target metadata, never <code>null</code> * @return root Element of the target metadata, never <code>null</code>
* *
* @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself. * @throws CrosswalkInternalException (<code>CrosswalkException</code>) failure of the crosswalk itself.
* @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object. * @throws CrosswalkObjectNotSupported (<code>CrosswalkException</code>) Cannot crosswalk this kind of DSpace object.
* @throws IOException I/O failure in services this calls * @throws IOException I/O failure in services this calls
* @throws SQLException Database failure in services this calls * @throws SQLException Database failure in services this calls
* @throws AuthorizeException current user not authorized for this operation. * @throws AuthorizeException current user not authorized for this operation.
*/ */
@Override @Override
public Element disseminateElement(DSpaceObject dso) public Element disseminateElement(DSpaceObject dso)
throws CrosswalkException, IOException, SQLException, throws CrosswalkException, IOException, SQLException,
AuthorizeException AuthorizeException
{ {
try try
{ {
PackageDisseminator dip = (PackageDisseminator) PackageDisseminator dip = (PackageDisseminator)
PluginManager.getNamedPlugin(PackageDisseminator.class, ROLE_PACKAGER_PLUGIN); PluginManager.getNamedPlugin(PackageDisseminator.class, ROLE_PACKAGER_PLUGIN);
if (dip == null) if (dip == null)
{ {
throw new CrosswalkInternalException("Cannot find a PackageDisseminator plugin named " + ROLE_PACKAGER_PLUGIN); throw new CrosswalkInternalException("Cannot find a PackageDisseminator plugin named " + ROLE_PACKAGER_PLUGIN);
} }
// Create a temporary file to disseminate into // Create a temporary file to disseminate into
String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir"); String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir");
File tempFile = File.createTempFile("RoleCrosswalkDisseminate" + dso.hashCode(), null, new File(tempDirectory)); File tempFile = File.createTempFile("RoleCrosswalkDisseminate" + dso.hashCode(), null, new File(tempDirectory));
tempFile.deleteOnExit(); tempFile.deleteOnExit();
// Initialize our packaging parameters // Initialize our packaging parameters
PackageParameters pparams; PackageParameters pparams;
if(this.getPackagingParameters()!=null) if(this.getPackagingParameters()!=null)
{ {
pparams = this.getPackagingParameters(); pparams = this.getPackagingParameters();
} }
else else
{ {
pparams = new PackageParameters(); pparams = new PackageParameters();
} }
//actually disseminate to our temp file. //actually disseminate to our temp file.
Context context = new Context(); Context context = new Context();
dip.disseminate(context, dso, pparams, tempFile); dip.disseminate(context, dso, pparams, tempFile);
// if we ended up with a Zero-length output file, // if we ended up with a Zero-length output file,
// this means dissemination was successful but had no results // this means dissemination was successful but had no results
if(tempFile.exists() && tempFile.length()==0) if(tempFile.exists() && tempFile.length()==0)
{ {
return null; return null;
} }
try try
{ {
//Try to parse our XML results (which were disseminated by the Packager) //Try to parse our XML results (which were disseminated by the Packager)
SAXBuilder builder = new SAXBuilder(); SAXBuilder builder = new SAXBuilder();
Document xmlDocument = builder.build(tempFile); Document xmlDocument = builder.build(tempFile);
//If XML parsed successfully, return root element of doc //If XML parsed successfully, return root element of doc
if(xmlDocument!=null && xmlDocument.hasRootElement()) if(xmlDocument!=null && xmlDocument.hasRootElement())
{ {
return xmlDocument.getRootElement(); return xmlDocument.getRootElement();
} }
else else
{ {
return null; return null;
} }
} }
catch (JDOMException je) catch (JDOMException je)
{ {
throw new MetadataValidationException("Error parsing Roles XML (see wrapped error message for more details) ",je); throw new MetadataValidationException("Error parsing Roles XML (see wrapped error message for more details) ",je);
} }
} }
catch (PackageException pe) catch (PackageException pe)
{ {
throw new CrosswalkInternalException("Failed to export Roles via packager (see wrapped error message for more details) ",pe); throw new CrosswalkInternalException("Failed to export Roles via packager (see wrapped error message for more details) ",pe);
} }
} }
// ---- Ingestion Methods ----------- // ---- Ingestion Methods -----------
/** /**
* Ingest a List of XML elements * Ingest a List of XML elements
* *
* @param context * @param context
* @param dso * @param dso
* @param metadata * @param metadata
* @throws CrosswalkException * @throws CrosswalkException
* @throws IOException * @throws IOException
* @throws SQLException * @throws SQLException
* @throws AuthorizeException * @throws AuthorizeException
*/ */
@Override @Override
public void ingest(Context context, DSpaceObject dso, List<Element> metadata) public void ingest(Context context, DSpaceObject dso, List<Element> metadata)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
if(!metadata.isEmpty()) if(!metadata.isEmpty())
{ {
ingest(context, dso, ((Element) metadata.get(0)).getParentElement()); ingest(context, dso, ((Element) metadata.get(0)).getParentElement());
} }
} }
/** /**
* Ingest a whole XML document, starting at specified root. * Ingest a whole XML document, starting at specified root.
* <P> * <P>
* This essentially just wraps a call to the configured Role PackageIngester. * This essentially just wraps a call to the configured Role PackageIngester.
* *
* @param context * @param context
* @param dso * @param dso
* @param root * @param root
* @throws CrosswalkException * @throws CrosswalkException
* @throws IOException * @throws IOException
* @throws SQLException * @throws SQLException
* @throws AuthorizeException * @throws AuthorizeException
*/ */
@Override @Override
public void ingest(Context context, DSpaceObject dso, Element root) public void ingest(Context context, DSpaceObject dso, Element root)
throws CrosswalkException, IOException, SQLException, AuthorizeException throws CrosswalkException, IOException, SQLException, AuthorizeException
{ {
if (dso.getType() != Constants.SITE && if (dso.getType() != Constants.SITE &&
dso.getType() != Constants.COMMUNITY && dso.getType() != Constants.COMMUNITY &&
dso.getType() != Constants.COLLECTION) dso.getType() != Constants.COLLECTION)
{ {
throw new CrosswalkObjectNotSupported("Role crosswalk only valid for Site, Community or Collection"); throw new CrosswalkObjectNotSupported("Role crosswalk only valid for Site, Community or Collection");
} }
//locate our "DSPACE-ROLES" PackageIngester plugin //locate our "DSPACE-ROLES" PackageIngester plugin
PackageIngester sip = (PackageIngester) PackageIngester sip = (PackageIngester)
PluginManager.getNamedPlugin(PackageIngester.class, ROLE_PACKAGER_PLUGIN); PluginManager.getNamedPlugin(PackageIngester.class, ROLE_PACKAGER_PLUGIN);
if (sip == null) if (sip == null)
{ {
throw new CrosswalkInternalException("Cannot find a PackageIngester plugin named " + ROLE_PACKAGER_PLUGIN); throw new CrosswalkInternalException("Cannot find a PackageIngester plugin named " + ROLE_PACKAGER_PLUGIN);
} }
// Initialize our packaging parameters // Initialize our packaging parameters
PackageParameters pparams; PackageParameters pparams;
if(this.getPackagingParameters()!=null) if(this.getPackagingParameters()!=null)
{ {
pparams = this.getPackagingParameters(); pparams = this.getPackagingParameters();
} }
else else
{ {
pparams = new PackageParameters(); pparams = new PackageParameters();
} }
// Initialize our license info // Initialize our license info
String license = null; String license = null;
if(this.getIngestionLicense()!=null) if(this.getIngestionLicense()!=null)
{ {
license = this.getIngestionLicense(); license = this.getIngestionLicense();
} }
// Create a temporary file to ingest from // Create a temporary file to ingest from
String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir"); String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir");
File tempFile = File.createTempFile("RoleCrosswalkIngest" + dso.hashCode(), null, new File(tempDirectory)); File tempFile = File.createTempFile("RoleCrosswalkIngest" + dso.hashCode(), null, new File(tempDirectory));
tempFile.deleteOnExit(); tempFile.deleteOnExit();
FileOutputStream fileOutStream = null; FileOutputStream fileOutStream = null;
try try
{ {
fileOutStream = new FileOutputStream(tempFile); fileOutStream = new FileOutputStream(tempFile);
XMLOutputter writer = new XMLOutputter(); XMLOutputter writer = new XMLOutputter();
writer.output(root, fileOutStream); writer.output(root, fileOutStream);
} }
finally finally
{ {
if (fileOutStream != null) if (fileOutStream != null)
{ {
fileOutStream.close(); fileOutStream.close();
} }
} }
//Actually call the ingester //Actually call the ingester
try try
{ {
sip.ingest(context, dso, tempFile, pparams, license); sip.ingest(context, dso, tempFile, pparams, license);
} }
catch (PackageException e) catch (PackageException e)
{ {
throw new CrosswalkInternalException(e); throw new CrosswalkInternalException(e);
} }
} }
} }

View File

@@ -1,51 +1,51 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.license; package org.dspace.content.license;
import java.util.Formattable; import java.util.Formattable;
import java.util.Formatter; import java.util.Formatter;
import org.dspace.core.PluginManager; import org.dspace.core.PluginManager;
/** /**
* Wrapper class to make formattable any argument used in the license template. * Wrapper class to make formattable any argument used in the license template.
* The formatter behavior is delegated to a specific class on "type" basis * The formatter behavior is delegated to a specific class on "type" basis
* using the PluginManager * using the PluginManager
* *
* @see Formattable * @see Formattable
* @see LicenseArgumentFormatter * @see LicenseArgumentFormatter
* @author bollini * @author bollini
* *
*/ */
public class FormattableArgument implements Formattable public class FormattableArgument implements Formattable
{ {
private String type; private String type;
private Object object; private Object object;
public FormattableArgument(String type, Object object) public FormattableArgument(String type, Object object)
{ {
this.type = type; this.type = type;
this.object = object; this.object = object;
} }
public void formatTo(Formatter formatter, int flags, int width, public void formatTo(Formatter formatter, int flags, int width,
int precision) int precision)
{ {
LicenseArgumentFormatter laf = (LicenseArgumentFormatter) PluginManager LicenseArgumentFormatter laf = (LicenseArgumentFormatter) PluginManager
.getNamedPlugin(LicenseArgumentFormatter.class, type); .getNamedPlugin(LicenseArgumentFormatter.class, type);
if (laf != null) if (laf != null)
{ {
laf.formatTo(formatter, flags, width, object, type); laf.formatTo(formatter, flags, width, object, type);
} }
else else
{ {
formatter.format(object.toString()); formatter.format(object.toString());
} }
} }
} }

View File

@@ -1,37 +1,37 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.license; package org.dspace.content.license;
import java.util.Formatter; import java.util.Formatter;
public interface LicenseArgumentFormatter public interface LicenseArgumentFormatter
{ {
/** /**
* Format the object following the <code>java.util.Formatter</code> rules. * 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 * 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 * 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" * supplied is expected that the implementer will work as if a "sample data"
* was requested. * was requested.
* *
* @see Formatter * @see Formatter
* @param formatter * @param formatter
* the current formatter that need to process the object * the current formatter that need to process the object
* @param flags * @param flags
* the flags option for the formatter * the flags option for the formatter
* @param width * @param width
* the width option for the formatter * the width option for the formatter
* @param object * @param object
* the object to be formatted * the object to be formatted
* @param type * @param type
* the type of the object (this is an alias not the class name! - * the type of the object (this is an alias not the class name! -
* i.e. item, collection, eperson, etc.) * i.e. item, collection, eperson, etc.)
*/ */
void formatTo(Formatter formatter, int flags, int width, Object object, void formatTo(Formatter formatter, int flags, int width, Object object,
String type); String type);
} }

View File

@@ -1,45 +1,45 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.license; package org.dspace.content.license;
import java.util.Formatter; import java.util.Formatter;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
/** /**
* This is a simple implementation of the LicenseArgumentFormatter for a * This is a simple implementation of the LicenseArgumentFormatter for a
* DSpaceObject. The formatter options width/precision are not take in care. * DSpaceObject. The formatter options width/precision are not take in care.
* *
* @author bollini * @author bollini
* *
*/ */
public class SimpleDSpaceObjectLicenseFormatter implements public class SimpleDSpaceObjectLicenseFormatter implements
LicenseArgumentFormatter LicenseArgumentFormatter
{ {
public void formatTo(Formatter formatter, int flags, int width, public void formatTo(Formatter formatter, int flags, int width,
Object object, String type) Object object, String type)
{ {
if (object == null) if (object == null)
{ {
formatter.format("sample "+type); formatter.format("sample "+type);
} }
else else
{ {
DSpaceObject dso = (DSpaceObject) object; DSpaceObject dso = (DSpaceObject) object;
String name = dso.getName(); String name = dso.getName();
if (name != null) if (name != null)
{ {
formatter.format(name); formatter.format(name);
} }
else else
{ {
formatter.format(""); formatter.format("");
} }
} }
} }
} }

View File

@@ -29,6 +29,7 @@ import org.dspace.content.Community;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.FormatIdentifier; import org.dspace.content.FormatIdentifier;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.crosswalk.CrosswalkException; import org.dspace.content.crosswalk.CrosswalkException;
import org.dspace.content.crosswalk.MetadataValidationException; import org.dspace.content.crosswalk.MetadataValidationException;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
@@ -36,7 +37,6 @@ import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.LogManager; import org.dspace.core.LogManager;
import org.dspace.handle.HandleManager; import org.dspace.handle.HandleManager;
import org.dspace.workflow.WorkflowItem;
import org.jdom.Element; import org.jdom.Element;
/** /**
@@ -459,24 +459,34 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester
manifest.crosswalkObjectOtherAdminMD(context, params, dso, callback); manifest.crosswalkObjectOtherAdminMD(context, params, dso, callback);
// -- Step 4 -- // -- 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 // Add all content files as bitstreams on new DSpace Object
if (type == Constants.ITEM) if (type == Constants.ITEM)
{ {
Item item = (Item) dso; 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 // Get collection this item is being submitted to
Collection collection = item.getOwningCollection(); Collection collection = item.getOwningCollection();
if (collection == null) if (collection == null)
{ {
// If an item doesn't have an owning-collection, that means it // Get the collection this workspace item belongs to
// has entered a workflow (and is not fully in the archive yet) if (wsi != null)
WorkflowItem wfi = WorkflowItem.findByItem(context, item);
// Get the collection this workflow item belongs to
if (wfi != 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. // have subclass manage license since it may be extra package file.
addLicense(context, item, license, collection, params); addLicense(context, item, license, collection, params);
// XXX FIXME // Finally, if item is still in the workspace, then we actually need
// should set lastModifiedTime e.g. when ingesting AIP. // to install it into the archive & assign its handle.
// maybe only do it in the finishObject() callback for AIP. 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 } // end if ITEM
else if (type == Constants.COLLECTION || type == Constants.COMMUNITY) else if (type == Constants.COLLECTION || type == Constants.COMMUNITY)
@@ -519,17 +534,6 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester
+ String.valueOf(type)); + 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 -- // -- Step 6 --
// Finish things up! // Finish things up!
@@ -635,7 +639,6 @@ public abstract class AbstractMETSIngester extends AbstractPackageIngester
if (dso.getType() == Constants.ITEM) if (dso.getType() == Constants.ITEM)
{ {
Item item = (Item) dso; Item item = (Item) dso;
// @TODO: maybe add an option to apply template Item on ingest??
// save manifest as a bitstream in Item if desired // save manifest as a bitstream in Item if desired
if (preserveManifest()) if (preserveManifest())

View File

@@ -1,191 +1,191 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.packager; package org.dspace.content.packager;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.ItemIterator; import org.dspace.content.ItemIterator;
import org.dspace.content.crosswalk.CrosswalkException; import org.dspace.content.crosswalk.CrosswalkException;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* An abstract implementation of a DSpace Package Disseminator, which * An abstract implementation of a DSpace Package Disseminator, which
* implements a few helper/utility methods that most (all?) PackageDisseminators * implements a few helper/utility methods that most (all?) PackageDisseminators
* may find useful. * may find useful.
* <P> * <P>
* First, implements recursive functionality in the disseminateAll() * First, implements recursive functionality in the disseminateAll()
* method of the PackageIngester interface. This method is setup to * method of the PackageIngester interface. This method is setup to
* recursively call disseminate() method. * recursively call disseminate() method.
* <P> * <P>
* All Package disseminators should either extend this abstract class * All Package disseminators should either extend this abstract class
* or implement <code>PackageDisseminator</code> to better suit their needs. * or implement <code>PackageDisseminator</code> to better suit their needs.
* *
* @author Tim Donohue * @author Tim Donohue
* @see PackageDisseminator * @see PackageDisseminator
*/ */
public abstract class AbstractPackageDisseminator public abstract class AbstractPackageDisseminator
implements PackageDisseminator implements PackageDisseminator
{ {
/** List of all successfully disseminated package files */ /** List of all successfully disseminated package files */
private List<File> packageFileList = new ArrayList<File>(); private List<File> packageFileList = new ArrayList<File>();
/** /**
* Recursively export one or more DSpace Objects as a series of packages. * 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 * This method will export the given DSpace Object as well as all referenced
* DSpaceObjects (e.g. child objects) into a series of packages. The * DSpaceObjects (e.g. child objects) into a series of packages. The
* initial object is exported to the location specified by the OutputStream. * initial object is exported to the location specified by the OutputStream.
* All other packages are exported to the same directory location. * All other packages are exported to the same directory location.
* <p> * <p>
* Package is any serialized representation of the item, at the discretion * Package is any serialized representation of the item, at the discretion
* of the implementing class. It does not have to include content bitstreams. * of the implementing class. It does not have to include content bitstreams.
* <br> * <br>
* Use the <code>params</code> parameter list to adjust the way the * Use the <code>params</code> parameter list to adjust the way the
* package is made, e.g. including a "<code>metadataOnly</code>" * package is made, e.g. including a "<code>metadataOnly</code>"
* parameter might make the package a bare manifest in XML * parameter might make the package a bare manifest in XML
* instead of a Zip file including manifest and contents. * instead of a Zip file including manifest and contents.
* <br> * <br>
* Throws an exception of the initial object is not acceptable or there is * Throws an exception of the initial object is not acceptable or there is
* a failure creating the package. * a failure creating the package.
* *
* @param context DSpace context. * @param context DSpace context.
* @param dso initial DSpace object * @param dso initial DSpace object
* @param params Properties-style list of options specific to this packager * @param params Properties-style list of options specific to this packager
* @param pkgFile File where initial package should be written. All other * @param pkgFile File where initial package should be written. All other
* packages will be written to the same directory as this File. * packages will be written to the same directory as this File.
* @throws PackageValidationException if package cannot be created or there is * @throws PackageValidationException if package cannot be created or there is
* a fatal error in creating it. * a fatal error in creating it.
*/ */
@Override @Override
public List<File> disseminateAll(Context context, DSpaceObject dso, public List<File> disseminateAll(Context context, DSpaceObject dso,
PackageParameters params, File pkgFile) PackageParameters params, File pkgFile)
throws PackageException, CrosswalkException, throws PackageException, CrosswalkException,
AuthorizeException, SQLException, IOException AuthorizeException, SQLException, IOException
{ {
//If unset, make sure the Parameters specifies this is a recursive dissemination //If unset, make sure the Parameters specifies this is a recursive dissemination
if(!params.recursiveModeEnabled()) if(!params.recursiveModeEnabled())
{ {
params.setRecursiveModeEnabled(true); params.setRecursiveModeEnabled(true);
} }
//try to disseminate the first object using provided PackageDisseminator //try to disseminate the first object using provided PackageDisseminator
disseminate(context, dso, params, pkgFile); disseminate(context, dso, params, pkgFile);
//check if package was disseminated //check if package was disseminated
if(pkgFile.exists()) if(pkgFile.exists())
{ {
//add to list of successfully disseminated packages //add to list of successfully disseminated packages
addToPackageList(pkgFile); addToPackageList(pkgFile);
//We can only recursively disseminate non-Items //We can only recursively disseminate non-Items
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages) //(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
if(dso.getType()!=Constants.ITEM) if(dso.getType()!=Constants.ITEM)
{ {
//Determine where first file package was disseminated to, as all //Determine where first file package was disseminated to, as all
//others will be written to same directory //others will be written to same directory
String pkgDirectory = pkgFile.getCanonicalFile().getParent(); String pkgDirectory = pkgFile.getCanonicalFile().getParent();
if(!pkgDirectory.endsWith(File.separator)) if(!pkgDirectory.endsWith(File.separator))
{ {
pkgDirectory += File.separator; pkgDirectory += File.separator;
} }
String fileExtension = PackageUtils.getFileExtension(pkgFile.getName()); String fileExtension = PackageUtils.getFileExtension(pkgFile.getName());
//recursively disseminate content, based on object type //recursively disseminate content, based on object type
switch (dso.getType()) switch (dso.getType())
{ {
case Constants.COLLECTION : case Constants.COLLECTION :
//Also find all Items in this Collection and disseminate //Also find all Items in this Collection and disseminate
Collection collection = (Collection) dso; Collection collection = (Collection) dso;
ItemIterator iterator = collection.getItems(); ItemIterator iterator = collection.getItems();
while(iterator.hasNext()) while(iterator.hasNext())
{ {
Item item = iterator.next(); Item item = iterator.next();
//disseminate all items (recursively!) //disseminate all items (recursively!)
String childFileName = pkgDirectory + PackageUtils.getPackageName(item, fileExtension); String childFileName = pkgDirectory + PackageUtils.getPackageName(item, fileExtension);
disseminateAll(context, item, params, new File(childFileName)); disseminateAll(context, item, params, new File(childFileName));
} }
break; break;
case Constants.COMMUNITY : case Constants.COMMUNITY :
//Also find all SubCommunities in this Community and disseminate //Also find all SubCommunities in this Community and disseminate
Community community = (Community) dso; Community community = (Community) dso;
Community[] subcommunities = community.getSubcommunities(); Community[] subcommunities = community.getSubcommunities();
for(int i=0; i<subcommunities.length; i++) for(int i=0; i<subcommunities.length; i++)
{ {
//disseminate all sub-communities (recursively!) //disseminate all sub-communities (recursively!)
String childFileName = pkgDirectory + PackageUtils.getPackageName(subcommunities[i], fileExtension); String childFileName = pkgDirectory + PackageUtils.getPackageName(subcommunities[i], fileExtension);
disseminateAll(context, subcommunities[i], params, new File(childFileName)); disseminateAll(context, subcommunities[i], params, new File(childFileName));
} }
//Also find all Collections in this Community and disseminate //Also find all Collections in this Community and disseminate
Collection[] collections = community.getCollections(); Collection[] collections = community.getCollections();
for(int i=0; i<collections.length; i++) for(int i=0; i<collections.length; i++)
{ {
//disseminate all collections (recursively!) //disseminate all collections (recursively!)
String childFileName = pkgDirectory + PackageUtils.getPackageName(collections[i], fileExtension); String childFileName = pkgDirectory + PackageUtils.getPackageName(collections[i], fileExtension);
disseminateAll(context, collections[i], params, new File(childFileName)); disseminateAll(context, collections[i], params, new File(childFileName));
} }
break; break;
case Constants.SITE : case Constants.SITE :
//Also find all top-level Communities and disseminate //Also find all top-level Communities and disseminate
Community[] topCommunities = Community.findAllTop(context); Community[] topCommunities = Community.findAllTop(context);
for(int i=0; i<topCommunities.length; i++) for(int i=0; i<topCommunities.length; i++)
{ {
//disseminate all top-level communities (recursively!) //disseminate all top-level communities (recursively!)
String childFileName = pkgDirectory + PackageUtils.getPackageName(topCommunities[i], fileExtension); String childFileName = pkgDirectory + PackageUtils.getPackageName(topCommunities[i], fileExtension);
disseminateAll(context, topCommunities[i], params, new File(childFileName)); disseminateAll(context, topCommunities[i], params, new File(childFileName));
} }
break; break;
}//end switch }//end switch
}//end if not an Item }//end if not an Item
}//end if pkgFile exists }//end if pkgFile exists
//return list of all successfully disseminated packages //return list of all successfully disseminated packages
return getPackageList(); return getPackageList();
} }
/** /**
* Add File to list of successfully disseminated package files * Add File to list of successfully disseminated package files
* @param file File * @param file File
*/ */
protected void addToPackageList(File f) protected void addToPackageList(File f)
{ {
//add to list of successfully disseminated packages //add to list of successfully disseminated packages
if(!packageFileList.contains(f)) if(!packageFileList.contains(f))
{ {
packageFileList.add(f); packageFileList.add(f);
} }
} }
/** /**
* Return List of all package Files which have been disseminated * Return List of all package Files which have been disseminated
* this instance of the Disseminator. * this instance of the Disseminator.
* <P> * <P>
* This list can be useful in reporting back to the user what content has * 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 * been disseminated as packages. It's used by disseminateAll() to report
* what packages were created. * what packages were created.
* *
* @return List of Files which correspond to the disseminated packages * @return List of Files which correspond to the disseminated packages
*/ */
protected List<File> getPackageList() protected List<File> getPackageList()
{ {
return packageFileList; return packageFileList;
} }
} }

View File

@@ -1,380 +1,380 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.packager; package org.dspace.content.packager;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.crosswalk.CrosswalkException; import org.dspace.content.crosswalk.CrosswalkException;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.LogManager; import org.dspace.core.LogManager;
/** /**
* An abstract implementation of a DSpace Package Ingester, which * An abstract implementation of a DSpace Package Ingester, which
* implements a few helper/utility methods that most (all?) PackageIngesters * implements a few helper/utility methods that most (all?) PackageIngesters
* may find useful. * may find useful.
* <P> * <P>
* First, implements recursive functionality in ingestAll() and replaceAll() * First, implements recursive functionality in ingestAll() and replaceAll()
* methods of the PackageIngester interface. These methods are setup to * methods of the PackageIngester interface. These methods are setup to
* recursively call ingest() and replace() respectively. * recursively call ingest() and replace() respectively.
* <P> * <P>
* Finally, it also implements several utility methods (createDSpaceObject(), * Finally, it also implements several utility methods (createDSpaceObject(),
* finishCreateItem(), updateDSpaceObject()) which subclasses may find useful. * finishCreateItem(), updateDSpaceObject()) which subclasses may find useful.
* This classes will allow subclasses to easily create/update objects without * This classes will allow subclasses to easily create/update objects without
* having to worry too much about normal DSpace submission workflows (which is * having to worry too much about normal DSpace submission workflows (which is
* taken care of in these utility methods). * taken care of in these utility methods).
* <P> * <P>
* All Package ingesters should either extend this abstract class * All Package ingesters should either extend this abstract class
* or implement <code>PackageIngester</code> to better suit their needs. * or implement <code>PackageIngester</code> to better suit their needs.
* *
* @author Tim Donohue * @author Tim Donohue
* @see PackageIngester * @see PackageIngester
*/ */
public abstract class AbstractPackageIngester public abstract class AbstractPackageIngester
implements PackageIngester implements PackageIngester
{ {
/** log4j category */ /** log4j category */
private static Logger log = Logger.getLogger(AbstractPackageIngester.class); private static Logger log = Logger.getLogger(AbstractPackageIngester.class);
/** /**
* References to other packages -- these are the next packages to ingest recursively * 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 * 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>>(); private Map<DSpaceObject,List<String>> packageReferences = new HashMap<DSpaceObject,List<String>>();
/** List of all successfully ingested/replaced DSpace objects */ /** List of all successfully ingested/replaced DSpace objects */
private List<DSpaceObject> dsoIngestedList = new ArrayList<DSpaceObject>(); private List<DSpaceObject> dsoIngestedList = new ArrayList<DSpaceObject>();
/** /**
* Recursively create one or more DSpace Objects out of the contents * Recursively create one or more DSpace Objects out of the contents
* of the ingested package (and all other referenced packages). * of the ingested package (and all other referenced packages).
* The initial object is created under the indicated parent. All other * The initial object is created under the indicated parent. All other
* objects are created based on their relationship to the initial object. * objects are created based on their relationship to the initial object.
* <p> * <p>
* For example, a scenario may be to create a Collection based on a * 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 * collection-level package, and also create an Item for every item-level
* package referenced by the collection-level package. * package referenced by the collection-level package.
* <p> * <p>
* The output of this method is one or more newly created <code>DspaceObject<code>s. * The output of this method is one or more newly created <code>DspaceObject<code>s.
* <p> * <p>
* The packager <em>may</em> choose not to implement <code>ingestAll</code>, * 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 * or simply forward the call to <code>ingest</code> if it is unable to support
* recursive ingestion. * recursive ingestion.
* <p> * <p>
* The deposit license (Only significant for Item) is passed * The deposit license (Only significant for Item) is passed
* explicitly as a string since there is no place for it in many * explicitly as a string since there is no place for it in many
* package formats. It is optional and may be given as * package formats. It is optional and may be given as
* <code>null</code>. * <code>null</code>.
* *
* @param context DSpace context. * @param context DSpace context.
* @param parent parent under which to create the initial object * @param parent parent under which to create the initial object
* (may be null -- in which case ingester must determine parent from package * (may be null -- in which case ingester must determine parent from package
* or throw an error). * or throw an error).
* @param pkgFile The initial package file to ingest * @param pkgFile The initial package file to ingest
* @param params Properties-style list of options (interpreted by each packager). * @param params Properties-style list of options (interpreted by each packager).
* @param license may be null, which takes default license. * @param license may be null, which takes default license.
* @return List of DSpaceObjects created * @return List of DSpaceObjects created
* *
* @throws PackageValidationException if initial package (or any referenced package) * @throws PackageValidationException if initial package (or any referenced package)
* is unacceptable or there is a fatal error in creating a DSpaceObject * is unacceptable or there is a fatal error in creating a DSpaceObject
* @throws UnsupportedOperationException if this packager does not * @throws UnsupportedOperationException if this packager does not
* implement <code>ingestAll</code> * implement <code>ingestAll</code>
*/ */
@Override @Override
public List<DSpaceObject> ingestAll(Context context, DSpaceObject parent, File pkgFile, public List<DSpaceObject> ingestAll(Context context, DSpaceObject parent, File pkgFile,
PackageParameters params, String license) PackageParameters params, String license)
throws PackageException, UnsupportedOperationException, throws PackageException, UnsupportedOperationException,
CrosswalkException, AuthorizeException, CrosswalkException, AuthorizeException,
SQLException, IOException SQLException, IOException
{ {
//If unset, make sure the Parameters specifies this is a recursive ingest //If unset, make sure the Parameters specifies this is a recursive ingest
if(!params.recursiveModeEnabled()) if(!params.recursiveModeEnabled())
{ {
params.setRecursiveModeEnabled(true); params.setRecursiveModeEnabled(true);
} }
//Initial DSpace Object to ingest //Initial DSpace Object to ingest
DSpaceObject dso = null; DSpaceObject dso = null;
//try to ingest the first package //try to ingest the first package
try try
{ {
//actually ingest pkg using provided PackageIngester //actually ingest pkg using provided PackageIngester
dso = ingest(context, parent, pkgFile, params, license); dso = ingest(context, parent, pkgFile, params, license);
} }
catch(IllegalStateException ie) catch(IllegalStateException ie)
{ {
// NOTE: if we encounter an IllegalStateException, this means the // NOTE: if we encounter an IllegalStateException, this means the
// handle is already in use and this object already exists. // handle is already in use and this object already exists.
//if we are skipping over (i.e. keeping) existing objects //if we are skipping over (i.e. keeping) existing objects
if(params.keepExistingModeEnabled()) if(params.keepExistingModeEnabled())
{ {
log.warn(LogManager.getHeader(context, "skip_package_ingest", "Object already exists, package-skipped=" + pkgFile)); 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) else // Pass this exception on -- which essentially causes a full rollback of all changes (this is the default)
{ {
throw ie; throw ie;
} }
} }
//as long as our first object was ingested successfully //as long as our first object was ingested successfully
if(dso!=null) if(dso!=null)
{ {
//add to list of successfully ingested objects //add to list of successfully ingested objects
addToIngestedList(dso); addToIngestedList(dso);
//We can only recursively ingest non-Items //We can only recursively ingest non-Items
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages) //(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
if(dso.getType()!=Constants.ITEM) if(dso.getType()!=Constants.ITEM)
{ {
//Check if we found child package references when ingesting this latest DSpaceObject //Check if we found child package references when ingesting this latest DSpaceObject
List<String> childPkgRefs = getPackageReferences(dso); List<String> childPkgRefs = getPackageReferences(dso);
//we can only recursively ingest child packages //we can only recursively ingest child packages
//if we have references to them //if we have references to them
if(childPkgRefs!=null && !childPkgRefs.isEmpty()) if(childPkgRefs!=null && !childPkgRefs.isEmpty())
{ {
//Recursively ingest each child package, using this current object as the parent DSpace Object //Recursively ingest each child package, using this current object as the parent DSpace Object
for(String childPkgRef : childPkgRefs) for(String childPkgRef : childPkgRefs)
{ {
// Remember where the additions start // Remember where the additions start
int oldSize = dsoIngestedList.size(); int oldSize = dsoIngestedList.size();
//Assume package reference is relative to current package location //Assume package reference is relative to current package location
File childPkg = new File(pkgFile.getAbsoluteFile().getParent(), childPkgRef); File childPkg = new File(pkgFile.getAbsoluteFile().getParent(), childPkgRef);
//fun, it's recursive! -- ingested referenced package as a child of current object //fun, it's recursive! -- ingested referenced package as a child of current object
ingestAll(context, dso, childPkg, params, license); ingestAll(context, dso, childPkg, params, license);
// A Collection can map to Items that it does not "own". // A Collection can map to Items that it does not "own".
// If a Collection package has an Item as a child, it // If a Collection package has an Item as a child, it
// should be mapped regardless of ownership. // should be mapped regardless of ownership.
// Note: Only perform this mapping if new items were ingested to this collection // Note: Only perform this mapping if new items were ingested to this collection
if (Constants.COLLECTION == dso.getType() && dsoIngestedList.size()>oldSize) if (Constants.COLLECTION == dso.getType() && dsoIngestedList.size()>oldSize)
{ {
// Since running 'ingestAll' on an item, will only ingest one Item at most, // Since running 'ingestAll' on an item, will only ingest one Item at most,
// Just make sure that item is mapped to this collection. // Just make sure that item is mapped to this collection.
Item childItem = (Item)dsoIngestedList.get(oldSize); Item childItem = (Item)dsoIngestedList.get(oldSize);
Collection collection = (Collection)dso; Collection collection = (Collection)dso;
if (!childItem.isIn(collection)) if (!childItem.isIn(collection))
{ {
collection.addItem(childItem); collection.addItem(childItem);
} }
} }
} }
}//end if child pkgs }//end if child pkgs
}//end if not an Item }//end if not an Item
}//end if DSpaceObject not null }//end if DSpaceObject not null
//Return list of all objects ingested //Return list of all objects ingested
return getIngestedList(); return getIngestedList();
} }
/** /**
* Recursively replace one or more DSpace Objects out of the contents * Recursively replace one or more DSpace Objects out of the contents
* of the ingested package (and all other referenced packages). * of the ingested package (and all other referenced packages).
* The initial object to replace is indicated by <code>dso</code>. All other * The initial object to replace is indicated by <code>dso</code>. All other
* objects are replaced based on information provided in the referenced packages. * objects are replaced based on information provided in the referenced packages.
* <p> * <p>
* For example, a scenario may be to replace a Collection based on a * For example, a scenario may be to replace a Collection based on a
* collection-level package, and also replace *every* Item in that collection * collection-level package, and also replace *every* Item in that collection
* based on the item-level packages referenced by the collection-level package. * based on the item-level packages referenced by the collection-level package.
* <p> * <p>
* Please note that since the <code>dso</code> input only specifies the * Please note that since the <code>dso</code> input only specifies the
* initial object to replace, any additional objects to replace must be * initial object to replace, any additional objects to replace must be
* determined based on the referenced packages (or initial package itself). * determined based on the referenced packages (or initial package itself).
* <p> * <p>
* The output of this method is one or more replaced <code>DspaceObject<code>s. * The output of this method is one or more replaced <code>DspaceObject<code>s.
* <p> * <p>
* The packager <em>may</em> choose not to implement <code>replaceAll</code>, * The packager <em>may</em> choose not to implement <code>replaceAll</code>,
* since it somewhat contradicts the archival nature of DSpace. It also * 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 * may choose to forward the call to <code>replace</code> if it is unable to
* support recursive replacement. * support recursive replacement.
* *
* @param context DSpace context. * @param context DSpace context.
* @param dso initial existing DSpace Object to be replaced, may be null * @param dso initial existing DSpace Object to be replaced, may be null
* if object to replace can be determined from package * if object to replace can be determined from package
* @param pkgFile The package file to ingest. * @param pkgFile The package file to ingest.
* @param params Properties-style list of options specific to this packager * @param params Properties-style list of options specific to this packager
* @return List of DSpaceObjects replaced * @return List of DSpaceObjects replaced
* *
* @throws PackageValidationException if initial package (or any referenced package) * @throws PackageValidationException if initial package (or any referenced package)
* is unacceptable or there is a fatal error in creating a DSpaceObject * is unacceptable or there is a fatal error in creating a DSpaceObject
* @throws UnsupportedOperationException if this packager does not * @throws UnsupportedOperationException if this packager does not
* implement <code>replaceAll</code> * implement <code>replaceAll</code>
*/ */
@Override @Override
public List<DSpaceObject> replaceAll(Context context, DSpaceObject dso, public List<DSpaceObject> replaceAll(Context context, DSpaceObject dso,
File pkgFile, PackageParameters params) File pkgFile, PackageParameters params)
throws PackageException, UnsupportedOperationException, throws PackageException, UnsupportedOperationException,
CrosswalkException, AuthorizeException, CrosswalkException, AuthorizeException,
SQLException, IOException SQLException, IOException
{ {
//If unset, make sure the Parameters specifies this is a recursive replace //If unset, make sure the Parameters specifies this is a recursive replace
if(!params.recursiveModeEnabled()) if(!params.recursiveModeEnabled())
{ {
params.setRecursiveModeEnabled(true); params.setRecursiveModeEnabled(true);
} }
//actually ingest pkg using provided PackageIngester, and replace object //actually ingest pkg using provided PackageIngester, and replace object
//NOTE: 'dso' may be null! If it is null, the PackageIngester must determine //NOTE: 'dso' may be null! If it is null, the PackageIngester must determine
// the object to be replaced from the package itself. // the object to be replaced from the package itself.
DSpaceObject replacedDso = replace(context, dso, pkgFile, params); DSpaceObject replacedDso = replace(context, dso, pkgFile, params);
//as long as our object was replaced successfully //as long as our object was replaced successfully
if(replacedDso!=null) if(replacedDso!=null)
{ {
//add to list of successfully replaced objects //add to list of successfully replaced objects
addToIngestedList(replacedDso); addToIngestedList(replacedDso);
//We can only recursively replace non-Items //We can only recursively replace non-Items
//(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages) //(NOTE: Items have no children, as Bitstreams/Bundles are created from Item packages)
if(replacedDso.getType()!=Constants.ITEM) if(replacedDso.getType()!=Constants.ITEM)
{ {
//Check if we found child package references when replacing this latest DSpaceObject //Check if we found child package references when replacing this latest DSpaceObject
List<String> childPkgRefs = getPackageReferences(replacedDso); List<String> childPkgRefs = getPackageReferences(replacedDso);
//we can only recursively ingest child packages //we can only recursively ingest child packages
//if we have references to them //if we have references to them
if(childPkgRefs!=null && !childPkgRefs.isEmpty()) if(childPkgRefs!=null && !childPkgRefs.isEmpty())
{ {
//Recursively replace each child package //Recursively replace each child package
for(String childPkgRef : childPkgRefs) for(String childPkgRef : childPkgRefs)
{ {
// Remember where the additions start // Remember where the additions start
int oldSize = dsoIngestedList.size(); int oldSize = dsoIngestedList.size();
//Assume package reference is relative to current package location //Assume package reference is relative to current package location
File childPkg = new File(pkgFile.getAbsoluteFile().getParent(), childPkgRef); File childPkg = new File(pkgFile.getAbsoluteFile().getParent(), childPkgRef);
//fun, it's recursive! -- replaced referenced package as a child of current object //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. // Pass object to replace as 'null', as we don't know which object to replace.
replaceAll(context, null, childPkg, params); replaceAll(context, null, childPkg, params);
// A Collection can map to Items that it does not "own". // A Collection can map to Items that it does not "own".
// If a Collection package has an Item as a child, it // If a Collection package has an Item as a child, it
// should be mapped regardless of ownership. // should be mapped regardless of ownership.
// If a Collection package has an Item as a child, it // If a Collection package has an Item as a child, it
// should be mapped regardless of ownership. // should be mapped regardless of ownership.
// Note: Only perform this mapping if new items were ingested to this collection // Note: Only perform this mapping if new items were ingested to this collection
if (Constants.COLLECTION == replacedDso.getType() && dsoIngestedList.size()>oldSize) if (Constants.COLLECTION == replacedDso.getType() && dsoIngestedList.size()>oldSize)
{ {
// Since running 'replaceAll' on an item, will only ingest one Item at most, // Since running 'replaceAll' on an item, will only ingest one Item at most,
// Just make sure that item is mapped to this collection. // Just make sure that item is mapped to this collection.
Item childItem = (Item)dsoIngestedList.get(oldSize); Item childItem = (Item)dsoIngestedList.get(oldSize);
Collection collection = (Collection)replacedDso; Collection collection = (Collection)replacedDso;
if (!childItem.isIn(collection)) if (!childItem.isIn(collection))
{ {
collection.addItem(childItem); collection.addItem(childItem);
} }
} }
} }
}//end if child pkgs }//end if child pkgs
}//end if not an Item }//end if not an Item
}//end if DSpaceObject not null }//end if DSpaceObject not null
//Return list of all objects replaced //Return list of all objects replaced
return getIngestedList(); return getIngestedList();
} }
/** /**
* During ingestion process, some submission information packages (SIPs) * During ingestion process, some submission information packages (SIPs)
* may reference other packages to be ingested (recursively). * may reference other packages to be ingested (recursively).
* <P> * <P>
* This method collects all references to other packages, so that we * This method collects all references to other packages, so that we
* can choose to recursively ingest them, as necessary, alongside the * can choose to recursively ingest them, as necessary, alongside the
* DSpaceObject created from the original SIP. * DSpaceObject created from the original SIP.
* <P> * <P>
* References are collected based on the DSpaceObject created from the SIP * References are collected based on the DSpaceObject created from the SIP
* (this way we keep the context of these references). * (this way we keep the context of these references).
* *
* @param dso DSpaceObject whose SIP referenced another package * @param dso DSpaceObject whose SIP referenced another package
* @param packageRef A reference to another package, which can be ingested after this one * @param packageRef A reference to another package, which can be ingested after this one
*/ */
public void addPackageReference(DSpaceObject dso, String packageRef) public void addPackageReference(DSpaceObject dso, String packageRef)
{ {
List<String> packageRefValues = null; List<String> packageRefValues = null;
// Check if we already have an entry for packages reference by this object // Check if we already have an entry for packages reference by this object
if(packageReferences.containsKey(dso)) if(packageReferences.containsKey(dso))
{ {
packageRefValues = packageReferences.get(dso); packageRefValues = packageReferences.get(dso);
} }
else else
{ {
//Create a new empty list of references //Create a new empty list of references
packageRefValues = new ArrayList<String>(); packageRefValues = new ArrayList<String>();
} }
//add this package reference to existing list and save //add this package reference to existing list and save
packageRefValues.add(packageRef); packageRefValues.add(packageRef);
packageReferences.put(dso, packageRefValues); packageReferences.put(dso, packageRefValues);
} }
/** /**
* Return a list of known SIP references from a newly created DSpaceObject. * Return a list of known SIP references from a newly created DSpaceObject.
* <P> * <P>
* These references should detail where another package exists which * These references should detail where another package exists which
* should be ingested alongside the current DSpaceObject. * should be ingested alongside the current DSpaceObject.
* <P> * <P>
* The <code>AbstractPackageIngester</code> or an equivalent SIP handler is expected * The <code>AbstractPackageIngester</code> or an equivalent SIP handler is expected
* to understand how to deal with these package references. * to understand how to deal with these package references.
* *
* @param dso DSpaceObject whose SIP referenced other SIPs * @param dso DSpaceObject whose SIP referenced other SIPs
* @return List of Strings which are the references to external submission ingestion packages * @return List of Strings which are the references to external submission ingestion packages
* (may be null if no SIPs were referenced) * (may be null if no SIPs were referenced)
*/ */
public List<String> getPackageReferences(DSpaceObject dso) public List<String> getPackageReferences(DSpaceObject dso)
{ {
return packageReferences.get(dso); return packageReferences.get(dso);
} }
/** /**
* Add DSpaceObject to list of successfully ingested/replaced objects * Add DSpaceObject to list of successfully ingested/replaced objects
* @param dso DSpaceObject * @param dso DSpaceObject
*/ */
protected void addToIngestedList(DSpaceObject dso) protected void addToIngestedList(DSpaceObject dso)
{ {
//add to list of successfully ingested objects //add to list of successfully ingested objects
if(!dsoIngestedList.contains(dso)) if(!dsoIngestedList.contains(dso))
{ {
dsoIngestedList.add(dso); dsoIngestedList.add(dso);
} }
} }
/** /**
* Return List of all DSpaceObjects which have been ingested/replaced by * Return List of all DSpaceObjects which have been ingested/replaced by
* this instance of the Ingester. * this instance of the Ingester.
* <P> * <P>
* This list can be useful in reporting back to the user what content has * 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 * been added or replaced. It's used by ingestAll() and replaceAll() to
* return this list of everything that was ingested/replaced. * return this list of everything that was ingested/replaced.
* *
* @return List of DSpaceObjects which have been added/replaced * @return List of DSpaceObjects which have been added/replaced
*/ */
protected List<DSpaceObject> getIngestedList() protected List<DSpaceObject> getIngestedList()
{ {
return dsoIngestedList; return dsoIngestedList;
} }
} }

View File

@@ -1,406 +1,406 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.content.packager; package org.dspace.content.packager;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import org.jdom.Element; import org.jdom.Element;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.DCValue; import org.dspace.content.DCValue;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.content.MetadataField; import org.dspace.content.MetadataField;
import org.dspace.content.MetadataSchema; import org.dspace.content.MetadataSchema;
import org.dspace.content.NonUniqueMetadataException; import org.dspace.content.NonUniqueMetadataException;
import org.dspace.content.crosswalk.CrosswalkException; import org.dspace.content.crosswalk.CrosswalkException;
import org.dspace.content.crosswalk.MetadataValidationException; import org.dspace.content.crosswalk.MetadataValidationException;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.Constants; import org.dspace.core.Constants;
/** /**
* Subclass of the METS packager framework to ingest a DSpace * Subclass of the METS packager framework to ingest a DSpace
* Archival Information Package (AIP). The AIP is intended to be, foremost, * Archival Information Package (AIP). The AIP is intended to be, foremost,
* a _complete_ and _accurate_ representation of one object in the DSpace * a _complete_ and _accurate_ representation of one object in the DSpace
* object model. An AIP contains all of the information needed to restore * object model. An AIP contains all of the information needed to restore
* the object precisely in another DSpace archive instance. * the object precisely in another DSpace archive instance.
* <p> * <p>
* This ingester recognizes two distinct types of AIPs: "Manifest-Only" and "External". * This ingester recognizes two distinct types of AIPs: "Manifest-Only" and "External".
* The Manifest-Only AIP, which is selected by specifying a PackageParameters * The Manifest-Only AIP, which is selected by specifying a PackageParameters
* key "manifestOnly" with the value "true", refers to all its contents by * 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 * 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 * 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". * 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. * The Manifest-Only AIP package format is simply a METS XML document serialized into a file.
* <p> * <p>
* An "external" AIP (the default), is a conventional Zip-file based package * An "external" AIP (the default), is a conventional Zip-file based package
* that includes copies of all bitstreams referenced by the object as well * that includes copies of all bitstreams referenced by the object as well
* as a serialized METS XML document in the path "mets.xml". * as a serialized METS XML document in the path "mets.xml".
* *
* Configuration keys: * Configuration keys:
* *
* # instructs which xwalk plugin to use for a given type of metadata * # instructs which xwalk plugin to use for a given type of metadata
* mets.dspaceAIP.ingest.crosswalk.{mdSecName} = {pluginName} * mets.dspaceAIP.ingest.crosswalk.{mdSecName} = {pluginName}
* mets.dspaceAIP.ingest.crosswalk.DC = QDC * mets.dspaceAIP.ingest.crosswalk.DC = QDC
* mets.dspaceAIP.ingest.crosswalk.DSpaceDepositLicense = NULLSTREAM * mets.dspaceAIP.ingest.crosswalk.DSpaceDepositLicense = NULLSTREAM
* *
* # Option to save METS manifest in the item: (default is false) * # Option to save METS manifest in the item: (default is false)
* mets.default.ingest.preserveManifest = false * mets.default.ingest.preserveManifest = false
* *
* @author Larry Stone * @author Larry Stone
* @author Tim Donohue * @author Tim Donohue
* @version $Revision: 1.1 $ * @version $Revision: 1.1 $
* *
* @see AbstractMETSIngester * @see AbstractMETSIngester
* @see AbstractPackageIngester * @see AbstractPackageIngester
* @see PackageIngester * @see PackageIngester
* @see org.dspace.content.packager.METSManifest * @see org.dspace.content.packager.METSManifest
*/ */
public class DSpaceAIPIngester public class DSpaceAIPIngester
extends AbstractMETSIngester extends AbstractMETSIngester
{ {
/** log4j category */ /** log4j category */
private static Logger log = Logger.getLogger(DSpaceAIPIngester.class); private static Logger log = Logger.getLogger(DSpaceAIPIngester.class);
/** /**
* Ensure it's an AIP generated by the complementary AIP disseminator. * Ensure it's an AIP generated by the complementary AIP disseminator.
*/ */
@Override @Override
void checkManifest(METSManifest manifest) void checkManifest(METSManifest manifest)
throws MetadataValidationException throws MetadataValidationException
{ {
String profile = manifest.getProfile(); String profile = manifest.getProfile();
if (profile == null) if (profile == null)
{ {
throw new MetadataValidationException("Cannot accept METS with no PROFILE attribute!"); throw new MetadataValidationException("Cannot accept METS with no PROFILE attribute!");
} }
else if (!profile.equals(DSpaceAIPDisseminator.PROFILE_1_0)) else if (!profile.equals(DSpaceAIPDisseminator.PROFILE_1_0))
{ {
throw new MetadataValidationException("METS has unacceptable PROFILE attribute, profile=" + profile); throw new MetadataValidationException("METS has unacceptable PROFILE attribute, profile=" + profile);
} }
} }
/** /**
* Choose DMD section(s) to crosswalk. * Choose DMD section(s) to crosswalk.
* <p> * <p>
* The algorithm is:<br> * The algorithm is:<br>
* 1. Use whatever the <code>dmd</code> parameter specifies as the primary DMD.<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> * 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 * 3. If (1) or (2) succeeds, crosswalk it and ignore all other DMDs with
* same GROUPID<br> * same GROUPID<br>
* 4. Crosswalk remaining DMDs not eliminated already. * 4. Crosswalk remaining DMDs not eliminated already.
*/ */
@Override @Override
public void crosswalkObjectDmd(Context context, DSpaceObject dso, public void crosswalkObjectDmd(Context context, DSpaceObject dso,
METSManifest manifest, METSManifest manifest,
MdrefManager callback, MdrefManager callback,
Element dmds[], PackageParameters params) Element dmds[], PackageParameters params)
throws CrosswalkException, PackageValidationException, throws CrosswalkException, PackageValidationException,
AuthorizeException, SQLException, IOException AuthorizeException, SQLException, IOException
{ {
int found = -1; int found = -1;
// Check to see what dmdSec the user specified in the 'dmd' parameter // Check to see what dmdSec the user specified in the 'dmd' parameter
String userDmd = null; String userDmd = null;
if (params != null) if (params != null)
{ {
userDmd = params.getProperty("dmd"); userDmd = params.getProperty("dmd");
} }
if (userDmd != null && userDmd.length() > 0) if (userDmd != null && userDmd.length() > 0)
{ {
for (int i = 0; i < dmds.length; ++i) for (int i = 0; i < dmds.length; ++i)
{ {
if (userDmd.equalsIgnoreCase(manifest.getMdType(dmds[i]))) if (userDmd.equalsIgnoreCase(manifest.getMdType(dmds[i])))
{ {
found = i; found = i;
} }
} }
} }
// DIM is preferred, if nothing specified by user // DIM is preferred, if nothing specified by user
if (found == -1) if (found == -1)
{ {
// DIM is preferred for AIP // DIM is preferred for AIP
for (int i = 0; i < dmds.length; ++i) for (int i = 0; i < dmds.length; ++i)
{ {
//NOTE: METS standard actually says this should be DIM (all uppercase). But, //NOTE: METS standard actually says this should be DIM (all uppercase). But,
// just in case, we're going to be a bit more forgiving. // just in case, we're going to be a bit more forgiving.
if ("DIM".equalsIgnoreCase(manifest.getMdType(dmds[i]))) if ("DIM".equalsIgnoreCase(manifest.getMdType(dmds[i])))
{ {
found = i; found = i;
} }
} }
} }
// MODS is acceptable otehrwise.. // MODS is acceptable otehrwise..
if (found == -1) if (found == -1)
{ {
for (int i = 0; i < dmds.length; ++i) for (int i = 0; i < dmds.length; ++i)
{ {
//NOTE: METS standard actually says this should be MODS (all uppercase). But, //NOTE: METS standard actually says this should be MODS (all uppercase). But,
// just in case, we're going to be a bit more forgiving. // just in case, we're going to be a bit more forgiving.
if ("MODS".equalsIgnoreCase(manifest.getMdType(dmds[i]))) if ("MODS".equalsIgnoreCase(manifest.getMdType(dmds[i])))
{ {
found = i; found = i;
} }
} }
} }
String groupID = null; String groupID = null;
if (found >= 0) if (found >= 0)
{ {
manifest.crosswalkItemDmd(context, params, dso, dmds[found], callback); manifest.crosswalkItemDmd(context, params, dso, dmds[found], callback);
groupID = dmds[found].getAttributeValue("GROUPID"); groupID = dmds[found].getAttributeValue("GROUPID");
if (groupID != null) if (groupID != null)
{ {
for (int i = 0; i < dmds.length; ++i) for (int i = 0; i < dmds.length; ++i)
{ {
String g = dmds[i].getAttributeValue("GROUPID"); String g = dmds[i].getAttributeValue("GROUPID");
if (g != null && !g.equals(groupID)) if (g != null && !g.equals(groupID))
{ {
manifest.crosswalkItemDmd(context, params, dso, dmds[i], callback); manifest.crosswalkItemDmd(context, params, dso, dmds[i], callback);
} }
} }
} }
} }
// otherwise take the first. Don't xwalk more than one because // otherwise take the first. Don't xwalk more than one because
// each xwalk _adds_ metadata, and could add duplicate fields. // each xwalk _adds_ metadata, and could add duplicate fields.
else if (dmds.length > 0) else if (dmds.length > 0)
{ {
manifest.crosswalkItemDmd(context, params, dso, dmds[0], callback); manifest.crosswalkItemDmd(context, params, dso, dmds[0], callback);
} }
// it's an error if there is nothing to crosswalk: // it's an error if there is nothing to crosswalk:
else else
{ {
throw new MetadataValidationException("DSpaceAIPIngester: Could not find an acceptable object-wide DMD section in manifest."); 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 * Ignore license when restoring an manifest-only AIP, since it should
* be a bitstream in the AIP already. * be a bitstream in the AIP already.
* Otherwise: Check item for license first; then, take deposit * Otherwise: Check item for license first; then, take deposit
* license supplied by explicit argument next, else use collection's * license supplied by explicit argument next, else use collection's
* default deposit license. * default deposit license.
* Normally the rightsMD crosswalks should provide a license. * Normally the rightsMD crosswalks should provide a license.
*/ */
@Override @Override
public void addLicense(Context context, Item item, String license, public void addLicense(Context context, Item item, String license,
Collection collection, PackageParameters params) Collection collection, PackageParameters params)
throws PackageValidationException, throws PackageValidationException,
AuthorizeException, SQLException, IOException AuthorizeException, SQLException, IOException
{ {
boolean newLicense = false; boolean newLicense = false;
if(!params.restoreModeEnabled()) if(!params.restoreModeEnabled())
{ {
//AIP is not being restored/replaced, so treat it like a SIP -- every new SIP needs a new license //AIP is not being restored/replaced, so treat it like a SIP -- every new SIP needs a new license
newLicense = true; newLicense = true;
} }
// Add deposit license if there isn't one in the object, // Add deposit license if there isn't one in the object,
// and it's not a restoration of an "manifestOnly" AIP: // and it's not a restoration of an "manifestOnly" AIP:
if (!params.getBooleanProperty("manifestOnly", false) && if (!params.getBooleanProperty("manifestOnly", false) &&
PackageUtils.findDepositLicense(context, item) == null) PackageUtils.findDepositLicense(context, item) == null)
{ {
newLicense = true; newLicense = true;
} }
if(newLicense) if(newLicense)
{ {
PackageUtils.addDepositLicense(context, license, item, collection); PackageUtils.addDepositLicense(context, license, item, collection);
} }
} }
/** /**
* Last change to fix up a DSpace Object. * Last change to fix up a DSpace Object.
* <P> * <P>
* For AIPs, if the object is an Item, we may want to make sure all of its * 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 * metadata fields already exist in the database (otherwise, the database
* will throw errors when we attempt to save/update the Item) * will throw errors when we attempt to save/update the Item)
* *
* @param context DSpace Context * @param context DSpace Context
* @param dso DSpace object * @param dso DSpace object
* @param params Packager Parameters * @param params Packager Parameters
*/ */
@Override @Override
public void finishObject(Context context, DSpaceObject dso, PackageParameters params) public void finishObject(Context context, DSpaceObject dso, PackageParameters params)
throws PackageValidationException, CrosswalkException, throws PackageValidationException, CrosswalkException,
AuthorizeException, SQLException, IOException AuthorizeException, SQLException, IOException
{ {
if(dso.getType()==Constants.ITEM) if(dso.getType()==Constants.ITEM)
{ {
// Check if 'createMetadataFields' option is enabled (default=true) // 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. // 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. // 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)) if (params.getBooleanProperty("createMetadataFields", true))
{ {
// We want to verify that all the Metadata Fields we've crosswalked // 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 // actually *exist* in the DB. If not, we'll try to create them
createMissingMetadataFields(context, (Item) dso); createMissingMetadataFields(context, (Item) dso);
} }
} }
} }
/** /**
* Nothing extra to do to bitstream after ingestion. * Nothing extra to do to bitstream after ingestion.
*/ */
@Override @Override
public void finishBitstream(Context context, public void finishBitstream(Context context,
Bitstream bs, Bitstream bs,
Element mfile, Element mfile,
METSManifest manifest, METSManifest manifest,
PackageParameters params) PackageParameters params)
throws MetadataValidationException, SQLException, AuthorizeException, IOException throws MetadataValidationException, SQLException, AuthorizeException, IOException
{ {
// nothing to do. // nothing to do.
} }
/** /**
* Return the type of DSpaceObject in this package; it is * Return the type of DSpaceObject in this package; it is
* in the TYPE attribute of the mets:mets element. * in the TYPE attribute of the mets:mets element.
*/ */
@Override @Override
public int getObjectType(METSManifest manifest) public int getObjectType(METSManifest manifest)
throws PackageValidationException throws PackageValidationException
{ {
Element mets = manifest.getMets(); Element mets = manifest.getMets();
String typeStr = mets.getAttributeValue("TYPE"); String typeStr = mets.getAttributeValue("TYPE");
if (typeStr == null || typeStr.length() == 0) if (typeStr == null || typeStr.length() == 0)
{ {
throw new PackageValidationException("Manifest is missing the required mets@TYPE attribute."); throw new PackageValidationException("Manifest is missing the required mets@TYPE attribute.");
} }
if (typeStr.startsWith("DSpace ")) if (typeStr.startsWith("DSpace "))
{ {
typeStr = typeStr.substring(7); typeStr = typeStr.substring(7);
} }
int type = Constants.getTypeID(typeStr); int type = Constants.getTypeID(typeStr);
if (type < 0) if (type < 0)
{ {
throw new PackageValidationException("Manifest has unrecognized value in mets@TYPE attribute: " + typeStr); throw new PackageValidationException("Manifest has unrecognized value in mets@TYPE attribute: " + typeStr);
} }
return type; return type;
} }
/** /**
* Name used to distinguish DSpace Configuration entries for this subclass. * Name used to distinguish DSpace Configuration entries for this subclass.
*/ */
@Override @Override
public String getConfigurationName() public String getConfigurationName()
{ {
return "dspaceAIP"; return "dspaceAIP";
} }
/** /**
* Verifies that all the unsaved, crosswalked metadata fields that have * Verifies that all the unsaved, crosswalked metadata fields that have
* been added to an Item actually exist in our Database. If they don't * been added to an Item actually exist in our Database. If they don't
* exist, they are created within the proper database tables. * exist, they are created within the proper database tables.
* <P> * <P>
* This method must be called *before* item.update(), as the call to update() * This method must be called *before* item.update(), as the call to update()
* will throw a SQLException when attempting to save any fields which * will throw a SQLException when attempting to save any fields which
* don't already exist in the database. * don't already exist in the database.
* <P> * <P>
* NOTE: This will NOT create a missing Metadata Schema (e.g. "dc" schema), * 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. * as we do not have enough info to create schemas on the fly.
* *
* @param context - DSpace Context * @param context - DSpace Context
* @param item - Item whose unsaved metadata fields we are testing * @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 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 * @throws PackageValidationException if a metadata schema doesn't exist, as we cannot autocreate a schema
*/ */
protected static void createMissingMetadataFields(Context context, Item item) protected static void createMissingMetadataFields(Context context, Item item)
throws PackageValidationException, AuthorizeException, IOException, SQLException throws PackageValidationException, AuthorizeException, IOException, SQLException
{ {
// Get all metadata fields/values currently added to this Item // Get all metadata fields/values currently added to this Item
DCValue allMD[] = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY); 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 each field, we'll check if it exists. If not, we'll create it.
for(DCValue md : allMD) for(DCValue md : allMD)
{ {
MetadataSchema mdSchema = null; MetadataSchema mdSchema = null;
MetadataField mdField = null; MetadataField mdField = null;
try try
{ {
//Try to access this Schema //Try to access this Schema
mdSchema = MetadataSchema.find(context, md.schema); mdSchema = MetadataSchema.find(context, md.schema);
//If Schema found, try to locate field from database //If Schema found, try to locate field from database
if(mdSchema!=null) if(mdSchema!=null)
{ {
mdField = MetadataField.findByElement(context, mdSchema.getSchemaID(), md.element, md.qualifier); mdField = MetadataField.findByElement(context, mdSchema.getSchemaID(), md.element, md.qualifier);
} }
} }
catch(SQLException se) catch(SQLException se)
{ {
//If a SQLException error is thrown, then this field does NOT exist in DB //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 //Set field to null, so we know we need to create it
mdField = null; mdField = null;
} }
// If our Schema was not found, we have a problem // If our Schema was not found, we have a problem
// We cannot easily create a Schema automatically -- as we don't know its Namespace // We cannot easily create a Schema automatically -- as we don't know its Namespace
if(mdSchema==null) 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."); 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 our Metadata Field is null, we will attempt to create it in the proper Schema
if(mdField==null) if(mdField==null)
{ {
try try
{ {
//initialize field (but don't set a scope note) & create it //initialize field (but don't set a scope note) & create it
mdField = new MetadataField(mdSchema, md.element, md.qualifier, null); mdField = new MetadataField(mdSchema, md.element, md.qualifier, null);
// NOTE: Only Adminstrators can create Metadata Fields -- create() will throw an AuthorizationException for non-Admins // NOTE: Only Adminstrators can create Metadata Fields -- create() will throw an AuthorizationException for non-Admins
mdField.create(context); mdField.create(context);
//log that field was created //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."); 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) catch(NonUniqueMetadataException ne)
{ // This exception should never happen, as we already checked to make sure the field doesn't exist. { // 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 // 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); 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 * Returns a user help string which should describe the
* additional valid command-line options that this packager * additional valid command-line options that this packager
* implementation will accept when using the <code>-o</code> or * implementation will accept when using the <code>-o</code> or
* <code>--option</code> flags with the Packager script. * <code>--option</code> flags with the Packager script.
* *
* @return a string describing additional command-line options available * @return a string describing additional command-line options available
* with this packager * with this packager
*/ */
@Override @Override
public String getParameterHelp() public String getParameterHelp()
{ {
String parentHelp = super.getParameterHelp(); String parentHelp = super.getParameterHelp();
//Return superclass help info, plus the extra parameters/options that this class supports //Return superclass help info, plus the extra parameters/options that this class supports
return parentHelp + return parentHelp +
"\n\n" + "\n\n" +
"* createMetadataFields=[boolean] " + "* createMetadataFields=[boolean] " +
"If true, ingest attempts to create any missing metadata fields." + "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)" + "If false, ingest will fail if a metadata field is encountered which doesn't already exist. (default = true)" +
"\n\n" + "\n\n" +
"* dmd=[dmdSecType] " + "* dmd=[dmdSecType] " +
"Type of the METS <dmdSec> which should be used to restore item metadata (defaults to DIM, then MODS)"; "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. * generic like ".xml", to accidentally get set to this format.
* @param context - the context. * @param context - the context.
* @param shortDesc - short descriptive name, used to locate existing format. * @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 desc - long description
* @param internal value for the 'internal' flag of a new format if created. * @param internal value for the 'internal' flag of a new format if created.
* @return BitstreamFormat object that was found or created. Never null. * @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) //(Note: Handle is not set until item is finished)
WorkspaceItem wsi = WorkspaceItem.create(context, (Collection)parent, params.useCollectionTemplate()); WorkspaceItem wsi = WorkspaceItem.create(context, (Collection)parent, params.useCollectionTemplate());
// Finish creating item with specified handle // Please note that we are returning an Item which is *NOT* yet in the Archive,
// (this will either install item immediately or start a workflow, based on params) // and doesn't yet have a handle assigned.
dso = finishCreateItem(context, wsi, handle, params); // This Item will remain "incomplete" until 'PackageUtils.finishCreateItem()' is called
return wsi.getItem();
return dso;
case Constants.SITE: case Constants.SITE:
return Site.find(context, Site.SITE_ID); 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) // default: skip workflow, but otherwise normal submission (i.e. package treated like a SIP)
else else
{ {
// Intall item immediately with the specified handle // Install item immediately with the specified handle
InstallItem.installItem(context, wsi, handle); InstallItem.installItem(context, wsi, handle);
// return newly installed item // return newly installed item
@@ -802,7 +801,7 @@ public class PackageUtils
* Also see the translateGroupNameForImport() method which does the opposite * Also see the translateGroupNameForImport() method which does the opposite
* of this method. * of this method.
* *
* @param relatedDso DSpaceObject associated with group * @param context current DSpace Context
* @param groupName Group's name * @param groupName Group's name
* @return the group name, with any internal IDs translated to Handles * @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 * Also see the translateGroupNameForExport() method which does the opposite
* of this method. * of this method.
* *
* @param relatedDso DSpaceObject associated with group * @param context current DSpace Context
* @param groupName Group's name * @param groupName Group's name
* @return the group name, with any Handles translated to internal IDs * @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.util.GregorianCalendar;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.text.ParseException; import java.text.ParseException;
import com.coverity.security.Escape;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
@@ -280,21 +280,8 @@ public final class Utils
*/ */
public static String addEntities(String value) 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. return Escape.html(value);
// that's why it's commented out.
// value = value.replaceAll("'", "&apos;");
value = value.replaceAll("<", "&lt;");
value = value.replaceAll(">", "&gt;");
return value;
} }
/** /**

View File

@@ -1,360 +1,360 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.curate; package org.dspace.curate;
// above package assignment temporary pending better aysnch release process // above package assignment temporary pending better aysnch release process
// package org.dspace.ctask.integrity; // package org.dspace.ctask.integrity;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream; import org.dspace.content.Bitstream;
import org.dspace.content.Bundle; import org.dspace.content.Bundle;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
/** ClamScan.java /** ClamScan.java
* *
* A set of methods to scan using the * A set of methods to scan using the
* clamav daemon. * clamav daemon.
* *
* TODO: add a check for the inputstream size limit * TODO: add a check for the inputstream size limit
* *
* @author wbossons * @author wbossons
*/ */
@Suspendable(invoked=Curator.Invoked.INTERACTIVE) @Suspendable(invoked=Curator.Invoked.INTERACTIVE)
public class ClamScan extends AbstractCurationTask public class ClamScan extends AbstractCurationTask
{ {
private static final int DEFAULT_CHUNK_SIZE = 4096;//2048 private static final int DEFAULT_CHUNK_SIZE = 4096;//2048
private static final byte[] INSTREAM = "zINSTREAM\0".getBytes(); private static final byte[] INSTREAM = "zINSTREAM\0".getBytes();
private static final byte[] PING = "zPING\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[] STATS = "nSTATS\n".getBytes();//prefix with z
private static final byte[] IDSESSION = "zIDSESSION\0".getBytes(); private static final byte[] IDSESSION = "zIDSESSION\0".getBytes();
private static final byte[] END = "zEND\0".getBytes(); private static final byte[] END = "zEND\0".getBytes();
private static final String PLUGIN_PREFIX = "clamav"; private static final String PLUGIN_PREFIX = "clamav";
private static final String INFECTED_MESSAGE = "had virus detected."; private static final String INFECTED_MESSAGE = "had virus detected.";
private static final String CLEAN_MESSAGE = "had no viruses 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 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 SCAN_FAIL_MESSAGE = "Error encountered using virus service - check setup";
private static final String NEW_ITEM_HANDLE = "in workflow"; private static final String NEW_ITEM_HANDLE = "in workflow";
private static Logger log = Logger.getLogger(ClamScan.class); private static Logger log = Logger.getLogger(ClamScan.class);
private static String host = null; private static String host = null;
private static int port = 0; private static int port = 0;
private static int timeout = 0; private static int timeout = 0;
private static boolean failfast = true; private static boolean failfast = true;
private int status = Curator.CURATE_UNSET; private int status = Curator.CURATE_UNSET;
private List<String> results = null; private List<String> results = null;
private Socket socket = null; private Socket socket = null;
private DataOutputStream dataOutputStream = null; private DataOutputStream dataOutputStream = null;
@Override @Override
public void init(Curator curator, String taskId) throws IOException public void init(Curator curator, String taskId) throws IOException
{ {
super.init(curator, taskId); super.init(curator, taskId);
host = ConfigurationManager.getProperty(PLUGIN_PREFIX, "service.host"); host = ConfigurationManager.getProperty(PLUGIN_PREFIX, "service.host");
port = ConfigurationManager.getIntProperty(PLUGIN_PREFIX, "service.port"); port = ConfigurationManager.getIntProperty(PLUGIN_PREFIX, "service.port");
timeout = ConfigurationManager.getIntProperty(PLUGIN_PREFIX, "socket.timeout"); timeout = ConfigurationManager.getIntProperty(PLUGIN_PREFIX, "socket.timeout");
failfast = ConfigurationManager.getBooleanProperty(PLUGIN_PREFIX, "scan.failfast"); failfast = ConfigurationManager.getBooleanProperty(PLUGIN_PREFIX, "scan.failfast");
} }
@Override @Override
public int perform(DSpaceObject dso) throws IOException public int perform(DSpaceObject dso) throws IOException
{ {
status = Curator.CURATE_SKIP; status = Curator.CURATE_SKIP;
logDebugMessage("The target dso is " + dso.getName()); logDebugMessage("The target dso is " + dso.getName());
if (dso instanceof Item) if (dso instanceof Item)
{ {
status = Curator.CURATE_SUCCESS; status = Curator.CURATE_SUCCESS;
Item item = (Item)dso; Item item = (Item)dso;
try try
{ {
openSession(); openSession();
} }
catch (IOException ioE) catch (IOException ioE)
{ {
// no point going further - set result and error out // no point going further - set result and error out
closeSession(); closeSession();
setResult(CONNECT_FAIL_MESSAGE); setResult(CONNECT_FAIL_MESSAGE);
return Curator.CURATE_ERROR; return Curator.CURATE_ERROR;
} }
try try
{ {
Bundle bundle = item.getBundles("ORIGINAL")[0]; Bundle bundle = item.getBundles("ORIGINAL")[0];
results = new ArrayList<String>(); results = new ArrayList<String>();
for (Bitstream bitstream : bundle.getBitstreams()) for (Bitstream bitstream : bundle.getBitstreams())
{ {
InputStream inputstream = bitstream.retrieve(); InputStream inputstream = bitstream.retrieve();
logDebugMessage("Scanning " + bitstream.getName() + " . . . "); logDebugMessage("Scanning " + bitstream.getName() + " . . . ");
int bstatus = scan(bitstream, inputstream, getItemHandle(item)); int bstatus = scan(bitstream, inputstream, getItemHandle(item));
inputstream.close(); inputstream.close();
if (bstatus == Curator.CURATE_ERROR) if (bstatus == Curator.CURATE_ERROR)
{ {
// no point going further - set result and error out // no point going further - set result and error out
setResult(SCAN_FAIL_MESSAGE); setResult(SCAN_FAIL_MESSAGE);
status = bstatus; status = bstatus;
break; break;
} }
if (failfast && bstatus == Curator.CURATE_FAIL) if (failfast && bstatus == Curator.CURATE_FAIL)
{ {
status = bstatus; status = bstatus;
break; break;
} }
else if (bstatus == Curator.CURATE_FAIL && else if (bstatus == Curator.CURATE_FAIL &&
status == Curator.CURATE_SUCCESS) status == Curator.CURATE_SUCCESS)
{ {
status = bstatus; status = bstatus;
} }
} }
} }
catch (AuthorizeException authE) catch (AuthorizeException authE)
{ {
throw new IOException(authE.getMessage(), authE); throw new IOException(authE.getMessage(), authE);
} }
catch (SQLException sqlE) catch (SQLException sqlE)
{ {
throw new IOException(sqlE.getMessage(), sqlE); throw new IOException(sqlE.getMessage(), sqlE);
} }
finally finally
{ {
closeSession(); closeSession();
} }
if (status != Curator.CURATE_ERROR) if (status != Curator.CURATE_ERROR)
{ {
formatResults(item); formatResults(item);
} }
} }
return status; return status;
} }
/** openSession /** openSession
* *
* This method opens a session. * This method opens a session.
*/ */
private void openSession() throws IOException private void openSession() throws IOException
{ {
socket = new Socket(); socket = new Socket();
try try
{ {
logDebugMessage("Connecting to " + host + ":" + port); logDebugMessage("Connecting to " + host + ":" + port);
socket.connect(new InetSocketAddress(host, port)); socket.connect(new InetSocketAddress(host, port));
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Failed to connect to clamd . . .", e); log.error("Failed to connect to clamd . . .", e);
throw (e); throw (e);
} }
try try
{ {
socket.setSoTimeout(timeout); socket.setSoTimeout(timeout);
} }
catch (SocketException e) catch (SocketException e)
{ {
log.error("Could not set socket timeout . . . " + timeout + "ms", e); log.error("Could not set socket timeout . . . " + timeout + "ms", e);
throw (new IOException(e)); throw (new IOException(e));
} }
try try
{ {
dataOutputStream = new DataOutputStream(socket.getOutputStream()); dataOutputStream = new DataOutputStream(socket.getOutputStream());
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Failed to open OutputStream . . . ", e); log.error("Failed to open OutputStream . . . ", e);
throw (e); throw (e);
} }
try try
{ {
dataOutputStream.write(IDSESSION); dataOutputStream.write(IDSESSION);
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Error initiating session with IDSESSION command . . . ", e); log.error("Error initiating session with IDSESSION command . . . ", e);
throw (e); throw (e);
} }
} }
/** closeSession /** closeSession
* *
* Close the IDSESSION in CLAMD * Close the IDSESSION in CLAMD
* *
* *
*/ */
private void closeSession() private void closeSession()
{ {
if (dataOutputStream != null) if (dataOutputStream != null)
{ {
try try
{ {
dataOutputStream.write(END); dataOutputStream.write(END);
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Exception closing dataOutputStream", e); log.error("Exception closing dataOutputStream", e);
} }
} }
try try
{ {
logDebugMessage("Closing the socket for ClamAv daemon . . . "); logDebugMessage("Closing the socket for ClamAv daemon . . . ");
socket.close(); socket.close();
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Exception closing socket", e); log.error("Exception closing socket", e);
} }
} }
/** scan /** scan
* *
* Issue the INSTREAM command and return the response to * Issue the INSTREAM command and return the response to
* and from the clamav daemon * and from the clamav daemon
* *
* @param the bitstream for reporting results * @param the bitstream for reporting results
* @param the InputStream to read * @param the InputStream to read
* @param the item handle for reporting results * @param the item handle for reporting results
* @return a ScanResult representing the server response * @return a ScanResult representing the server response
* @throws IOException * @throws IOException
*/ */
final static byte[] buffer = new byte[DEFAULT_CHUNK_SIZE];; final static byte[] buffer = new byte[DEFAULT_CHUNK_SIZE];;
private int scan(Bitstream bitstream, InputStream inputstream, String itemHandle) private int scan(Bitstream bitstream, InputStream inputstream, String itemHandle)
{ {
try try
{ {
dataOutputStream.write(INSTREAM); dataOutputStream.write(INSTREAM);
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Error writing INSTREAM command . . ."); log.error("Error writing INSTREAM command . . .");
return Curator.CURATE_ERROR; return Curator.CURATE_ERROR;
} }
int read = DEFAULT_CHUNK_SIZE; int read = DEFAULT_CHUNK_SIZE;
while (read == DEFAULT_CHUNK_SIZE) while (read == DEFAULT_CHUNK_SIZE)
{ {
try try
{ {
read = inputstream.read(buffer); read = inputstream.read(buffer);
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Failed attempting to read the InputStream . . . "); log.error("Failed attempting to read the InputStream . . . ");
return Curator.CURATE_ERROR; return Curator.CURATE_ERROR;
} }
if (read == -1) if (read == -1)
{ {
break; break;
} }
try try
{ {
dataOutputStream.writeInt(read); dataOutputStream.writeInt(read);
dataOutputStream.write(buffer, 0, read); dataOutputStream.write(buffer, 0, read);
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Could not write to the socket . . . "); log.error("Could not write to the socket . . . ");
return Curator.CURATE_ERROR; return Curator.CURATE_ERROR;
} }
} }
try try
{ {
dataOutputStream.writeInt(0); dataOutputStream.writeInt(0);
dataOutputStream.flush(); dataOutputStream.flush();
} }
catch (IOException e) catch (IOException e)
{ {
log.error("Error writing zero-length chunk to socket") ; log.error("Error writing zero-length chunk to socket") ;
return Curator.CURATE_ERROR; return Curator.CURATE_ERROR;
} }
try try
{ {
read = socket.getInputStream().read(buffer); read = socket.getInputStream().read(buffer);
} }
catch (IOException e) catch (IOException e)
{ {
log.error( "Error reading result from socket"); log.error( "Error reading result from socket");
return Curator.CURATE_ERROR; return Curator.CURATE_ERROR;
} }
if (read > 0) if (read > 0)
{ {
String response = new String(buffer, 0, read); String response = new String(buffer, 0, read);
logDebugMessage("Response: " + response); logDebugMessage("Response: " + response);
if (response.indexOf("FOUND") != -1) if (response.indexOf("FOUND") != -1)
{ {
String itemMsg = "item - " + itemHandle + ": "; String itemMsg = "item - " + itemHandle + ": ";
String bsMsg = "bitstream - " + bitstream.getName() + String bsMsg = "bitstream - " + bitstream.getName() +
": SequenceId - " + bitstream.getSequenceID() + ": infected"; ": SequenceId - " + bitstream.getSequenceID() + ": infected";
report(itemMsg + bsMsg); report(itemMsg + bsMsg);
results.add(bsMsg); results.add(bsMsg);
return Curator.CURATE_FAIL; return Curator.CURATE_FAIL;
} }
else else
{ {
return Curator.CURATE_SUCCESS; return Curator.CURATE_SUCCESS;
} }
} }
return Curator.CURATE_ERROR; return Curator.CURATE_ERROR;
} }
private void formatResults(Item item) throws IOException private void formatResults(Item item) throws IOException
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("Item: ").append(getItemHandle(item)).append(" "); sb.append("Item: ").append(getItemHandle(item)).append(" ");
if (status == Curator.CURATE_FAIL) if (status == Curator.CURATE_FAIL)
{ {
sb.append(INFECTED_MESSAGE); sb.append(INFECTED_MESSAGE);
int count = 0; int count = 0;
for (String scanresult : results) for (String scanresult : results)
{ {
sb.append("\n").append(scanresult).append("\n"); sb.append("\n").append(scanresult).append("\n");
count++; count++;
} }
sb.append(count).append(" virus(es) found. ") sb.append(count).append(" virus(es) found. ")
.append(" failfast: ").append(failfast); .append(" failfast: ").append(failfast);
} }
else else
{ {
sb.append(CLEAN_MESSAGE); sb.append(CLEAN_MESSAGE);
} }
setResult(sb.toString()); setResult(sb.toString());
} }
private static String getItemHandle(Item item) private static String getItemHandle(Item item)
{ {
String handle = item.getHandle(); String handle = item.getHandle();
return (handle != null) ? handle: NEW_ITEM_HANDLE; return (handle != null) ? handle: NEW_ITEM_HANDLE;
} }
private void logDebugMessage(String message) private void logDebugMessage(String message)
{ {
if (log.isDebugEnabled()) if (log.isDebugEnabled())
{ {
log.debug(message); log.debug(message);
} }
} }
} }

View File

@@ -351,7 +351,7 @@ public class EPerson extends DSpaceObject
} }
// Get all the epeople that match the query // Get all the epeople that match the query
TableRowIterator rows = DatabaseManager.queryTable(context, "eperson", TableRowIterator rows = DatabaseManager.query(context,
dbquery, paramArr); dbquery, paramArr);
try 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 // 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. // 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); "SELECT * FROM eperson ORDER BY "+s);
try try
@@ -955,7 +955,7 @@ public class EPerson extends DSpaceObject
List<String> tableList = new ArrayList<String>(); List<String> tableList = new ArrayList<String>();
// check for eperson in item table // check for eperson in item table
TableRowIterator tri = DatabaseManager.queryTable(myContext, "item", TableRowIterator tri = DatabaseManager.query(myContext,
"SELECT * from item where submitter_id= ? ", "SELECT * from item where submitter_id= ? ",
getID()); getID());
@@ -976,7 +976,7 @@ public class EPerson extends DSpaceObject
} }
// check for eperson in workflowitem table // check for eperson in workflowitem table
tri = DatabaseManager.queryTable(myContext, "workflowitem", tri = DatabaseManager.query(myContext,
"SELECT * from workflowitem where owner= ? ", "SELECT * from workflowitem where owner= ? ",
getID()); getID());
@@ -997,7 +997,7 @@ public class EPerson extends DSpaceObject
} }
// check for eperson in tasklistitem table // check for eperson in tasklistitem table
tri = DatabaseManager.queryTable(myContext, "tasklistitem", tri = DatabaseManager.query(myContext,
"SELECT * from tasklistitem where eperson_id= ? ", "SELECT * from tasklistitem where eperson_id= ? ",
getID()); getID());

View File

@@ -1,421 +1,421 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.harvest; package org.dspace.harvest;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.storage.rdbms.DatabaseManager; import org.dspace.storage.rdbms.DatabaseManager;
import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.storage.rdbms.TableRowIterator;
import org.dspace.storage.rdbms.TableRow; import org.dspace.storage.rdbms.TableRow;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
/** /**
* @author Alexey Maslov * @author Alexey Maslov
*/ */
public class HarvestedCollection public class HarvestedCollection
{ {
private Context context; private Context context;
private TableRow harvestRow; private TableRow harvestRow;
public static final int TYPE_NONE = 0; public static final int TYPE_NONE = 0;
public static final int TYPE_DMD = 1; public static final int TYPE_DMD = 1;
public static final int TYPE_DMDREF = 2; public static final int TYPE_DMDREF = 2;
public static final int TYPE_FULL = 3; public static final int TYPE_FULL = 3;
public static final int STATUS_READY = 0; public static final int STATUS_READY = 0;
public static final int STATUS_BUSY = 1; public static final int STATUS_BUSY = 1;
public static final int STATUS_QUEUED = 2; public static final int STATUS_QUEUED = 2;
public static final int STATUS_OAI_ERROR = 3; public static final int STATUS_OAI_ERROR = 3;
public static final int STATUS_UNKNOWN_ERROR = -1; public static final int STATUS_UNKNOWN_ERROR = -1;
/* /*
* collection_id | integer | not null * collection_id | integer | not null
harvest_type | integer | harvest_type | integer |
oai_source | text | oai_source | text |
oai_set_id | text | oai_set_id | text |
harvest_message | text | harvest_message | text |
metadata_config_id | text | metadata_config_id | text |
harvest_status | integer | harvest_status | integer |
harvest_start_time | timestamp with time zone | harvest_start_time | timestamp with time zone |
*/ */
// TODO: make sure this guy knows to lock people out if the status is not zero. // 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 // 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. // to stop an ongoing harvest before they can edit the settings.
HarvestedCollection(Context c, TableRow row) HarvestedCollection(Context c, TableRow row)
{ {
context = c; context = c;
harvestRow = row; harvestRow = row;
} }
public static void exists(Context c) throws SQLException { public static void exists(Context c) throws SQLException {
DatabaseManager.queryTable(c, "harvested_collection", "SELECT COUNT(*) FROM harvested_collection"); DatabaseManager.queryTable(c, "harvested_collection", "SELECT COUNT(*) FROM harvested_collection");
} }
/** /**
* Find the harvest settings corresponding to this collection * Find the harvest settings corresponding to this collection
* @return a HarvestInstance object corresponding to this collection's settings, null if not found. * @return a HarvestInstance object corresponding to this collection's settings, null if not found.
*/ */
public static HarvestedCollection find(Context c, int collectionId) throws SQLException public static HarvestedCollection find(Context c, int collectionId) throws SQLException
{ {
TableRow row = DatabaseManager.findByUnique(c, "harvested_collection", "collection_id", collectionId); TableRow row = DatabaseManager.findByUnique(c, "harvested_collection", "collection_id", collectionId);
if (row == null) { if (row == null) {
return null; return null;
} }
return new HarvestedCollection(c, row); return new HarvestedCollection(c, row);
} }
/** /**
* Create a new harvest instance row for a specified collection. * Create a new harvest instance row for a specified collection.
* @return a new HarvestInstance object * @return a new HarvestInstance object
*/ */
public static HarvestedCollection create(Context c, int collectionId) throws SQLException { public static HarvestedCollection create(Context c, int collectionId) throws SQLException {
TableRow row = DatabaseManager.row("harvested_collection"); TableRow row = DatabaseManager.row("harvested_collection");
row.setColumn("collection_id", collectionId); row.setColumn("collection_id", collectionId);
row.setColumn("harvest_type", 0); row.setColumn("harvest_type", 0);
DatabaseManager.insert(c, row); DatabaseManager.insert(c, row);
return new HarvestedCollection(c, row); return new HarvestedCollection(c, row);
} }
/** Returns whether the specified collection is harvestable, i.e. whether its harvesting /** 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 * options are set up correctly. This is distinct from "ready", since this collection may
* be in process of being harvested. * be in process of being harvested.
*/ */
public static boolean isHarvestable(Context c, int collectionId) throws SQLException public static boolean isHarvestable(Context c, int collectionId) throws SQLException
{ {
HarvestedCollection hc = HarvestedCollection.find(c, collectionId); HarvestedCollection hc = HarvestedCollection.find(c, collectionId);
if (hc != null && hc.getHarvestType() > 0 && hc.getOaiSource() != null && hc.getOaiSetId() != null && if (hc != null && hc.getHarvestType() > 0 && hc.getOaiSource() != null && hc.getOaiSetId() != null &&
hc.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) { hc.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) {
return true; return true;
} }
return false; return false;
} }
/** Returns whether this harvest instance is actually harvestable, i.e. whether its settings /** 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 * options are set up correctly. This is distinct from "ready", since this collection may
* be in process of being harvested. * be in process of being harvested.
*/ */
public boolean isHarvestable() throws SQLException public boolean isHarvestable() throws SQLException
{ {
if (this.getHarvestType() > 0 && this.getOaiSource() != null && this.getOaiSetId() != null && if (this.getHarvestType() > 0 && this.getOaiSource() != null && this.getOaiSetId() != null &&
this.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) { this.getHarvestStatus() != HarvestedCollection.STATUS_UNKNOWN_ERROR) {
return true; return true;
} }
return false; return false;
} }
/** Returns whether the specified collection is ready for immediate harvest. /** Returns whether the specified collection is ready for immediate harvest.
*/ */
public static boolean isReady(Context c, int collectionId) throws SQLException public static boolean isReady(Context c, int collectionId) throws SQLException
{ {
HarvestedCollection hc = HarvestedCollection.find(c, collectionId); HarvestedCollection hc = HarvestedCollection.find(c, collectionId);
return hc.isReady(); return hc.isReady();
} }
public boolean isReady() throws SQLException public boolean isReady() throws SQLException
{ {
if (this.isHarvestable() && (this.getHarvestStatus() == HarvestedCollection.STATUS_READY || this.getHarvestStatus() == HarvestedCollection.STATUS_OAI_ERROR)) if (this.isHarvestable() && (this.getHarvestStatus() == HarvestedCollection.STATUS_READY || this.getHarvestStatus() == HarvestedCollection.STATUS_OAI_ERROR))
{ {
return true; return true;
} }
return false; return false;
} }
/** Find all collections that are set up for harvesting /** Find all collections that are set up for harvesting
* *
* return: list of collection id's * return: list of collection id's
* @throws SQLException * @throws SQLException
*/ */
public static List<Integer> findAll(Context c) throws SQLException public static List<Integer> findAll(Context c) throws SQLException
{ {
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection", TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
"SELECT * FROM harvested_collection"); "SELECT * FROM harvested_collection");
List<Integer> collectionIds = new ArrayList<Integer>(); List<Integer> collectionIds = new ArrayList<Integer>();
while (tri.hasNext()) while (tri.hasNext())
{ {
TableRow row = tri.next(); TableRow row = tri.next();
collectionIds.add(row.getIntColumn("collection_id")); collectionIds.add(row.getIntColumn("collection_id"));
} }
return collectionIds; return collectionIds;
} }
/** Find all collections that are ready for harvesting /** Find all collections that are ready for harvesting
* *
* return: list of collection id's * return: list of collection id's
* @throws SQLException * @throws SQLException
*/ */
public static List<Integer> findReady(Context c) throws SQLException public static List<Integer> findReady(Context c) throws SQLException
{ {
int harvestInterval = ConfigurationManager.getIntProperty("harvester.harvestFrequency"); int harvestInterval = ConfigurationManager.getIntProperty("harvester.harvestFrequency");
if (harvestInterval == 0) if (harvestInterval == 0)
{ {
harvestInterval = 720; harvestInterval = 720;
} }
int expirationInterval = ConfigurationManager.getIntProperty("harvester.threadTimeout"); int expirationInterval = ConfigurationManager.getIntProperty("harvester.threadTimeout");
if (expirationInterval == 0) if (expirationInterval == 0)
{ {
expirationInterval = 24; expirationInterval = 24;
} }
Date startTime; Date startTime;
Date expirationTime; Date expirationTime;
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date()); calendar.setTime(new Date());
calendar.add(Calendar.MINUTE, -1 * harvestInterval); calendar.add(Calendar.MINUTE, -1 * harvestInterval);
startTime = calendar.getTime(); startTime = calendar.getTime();
calendar.setTime(startTime); calendar.setTime(startTime);
calendar.add(Calendar.HOUR, -2 * expirationInterval); calendar.add(Calendar.HOUR, -2 * expirationInterval);
expirationTime = calendar.getTime(); 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). */ /* 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", 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", "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())); 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>(); List<Integer> collectionIds = new ArrayList<Integer>();
while (tri.hasNext()) while (tri.hasNext())
{ {
TableRow row = tri.next(); TableRow row = tri.next();
collectionIds.add(row.getIntColumn("collection_id")); collectionIds.add(row.getIntColumn("collection_id"));
} }
return collectionIds; return collectionIds;
} }
/** /**
* Find all collections with the specified status flag * Find all collections with the specified status flag
* @param c * @param c
* @param status see HarvestInstance.STATUS_... * @param status see HarvestInstance.STATUS_...
* @return * @return
* @throws SQLException * @throws SQLException
*/ */
public static List<Integer> findByStatus(Context c, int status) throws SQLException { public static List<Integer> findByStatus(Context c, int status) throws SQLException {
TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection", TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
"SELECT * FROM harvested_collection WHERE harvest_status = ?", status); "SELECT * FROM harvested_collection WHERE harvest_status = ?", status);
List<Integer> collectionIds = new ArrayList<Integer>(); List<Integer> collectionIds = new ArrayList<Integer>();
while (tri.hasNext()) while (tri.hasNext())
{ {
TableRow row = tri.next(); TableRow row = tri.next();
collectionIds.add(row.getIntColumn("collection_id")); collectionIds.add(row.getIntColumn("collection_id"));
} }
return collectionIds; return collectionIds;
} }
/** Find the collection that was harvested the longest time ago. /** Find the collection that was harvested the longest time ago.
* @throws SQLException * @throws SQLException
*/ */
public static Integer findOldestHarvest (Context c) 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"; 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"))) 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"; 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", TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
query, 0, 0); query, 0, 0);
TableRow row = tri.next(); TableRow row = tri.next();
if (row != null) if (row != null)
{ {
return row.getIntColumn("collection_id"); return row.getIntColumn("collection_id");
} }
else else
{ {
return -1; return -1;
} }
} }
/** Find the collection that was harvested most recently. /** Find the collection that was harvested most recently.
* @throws SQLException * @throws SQLException
*/ */
public static Integer findNewestHarvest (Context c) 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"; 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"))) 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"; 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", TableRowIterator tri = DatabaseManager.queryTable(c, "harvested_collection",
query , 0, 0); query , 0, 0);
TableRow row = tri.next(); TableRow row = tri.next();
if (row != null) if (row != null)
{ {
return row.getIntColumn("collection_id"); return row.getIntColumn("collection_id");
} }
else else
{ {
return -1; return -1;
} }
} }
/** /**
* A function to set all harvesting-related parameters at once * A function to set all harvesting-related parameters at once
*/ */
public void setHarvestParams(int type, String oaiSource, String oaiSetId, String mdConfigId) { public void setHarvestParams(int type, String oaiSource, String oaiSetId, String mdConfigId) {
setHarvestType(type); setHarvestType(type);
setOaiSource(oaiSource); setOaiSource(oaiSource);
setOaiSetId(oaiSetId); setOaiSetId(oaiSetId);
setHarvestMetadataConfig(mdConfigId); setHarvestMetadataConfig(mdConfigId);
} }
/* Setters for the appropriate harvesting-related columns */ /* Setters for the appropriate harvesting-related columns */
public void setHarvestType(int type) { public void setHarvestType(int type) {
harvestRow.setColumn("harvest_type",type); harvestRow.setColumn("harvest_type",type);
} }
/** /**
* Sets the current status of the collection. * Sets the current status of the collection.
* *
* @param status a HarvestInstance.STATUS_... constant * @param status a HarvestInstance.STATUS_... constant
*/ */
public void setHarvestStatus(int status) { public void setHarvestStatus(int status) {
harvestRow.setColumn("harvest_status",status); harvestRow.setColumn("harvest_status",status);
} }
public void setOaiSource(String oaiSource) { public void setOaiSource(String oaiSource) {
if (oaiSource == null || oaiSource.length() == 0) { if (oaiSource == null || oaiSource.length() == 0) {
harvestRow.setColumnNull("oai_source"); harvestRow.setColumnNull("oai_source");
} }
else { else {
harvestRow.setColumn("oai_source",oaiSource); harvestRow.setColumn("oai_source",oaiSource);
} }
} }
public void setOaiSetId(String oaiSetId) { public void setOaiSetId(String oaiSetId) {
if (oaiSetId == null || oaiSetId.length() == 0) { if (oaiSetId == null || oaiSetId.length() == 0) {
harvestRow.setColumnNull("oai_set_id"); harvestRow.setColumnNull("oai_set_id");
} }
else { else {
harvestRow.setColumn("oai_set_id",oaiSetId); harvestRow.setColumn("oai_set_id",oaiSetId);
} }
} }
public void setHarvestMetadataConfig(String mdConfigId) { public void setHarvestMetadataConfig(String mdConfigId) {
if (mdConfigId == null || mdConfigId.length() == 0) { if (mdConfigId == null || mdConfigId.length() == 0) {
harvestRow.setColumnNull("metadata_config_id"); harvestRow.setColumnNull("metadata_config_id");
} }
else { else {
harvestRow.setColumn("metadata_config_id",mdConfigId); harvestRow.setColumn("metadata_config_id",mdConfigId);
} }
} }
public void setHarvestResult(Date date, String message) { public void setHarvestResult(Date date, String message) {
if (date == null) { if (date == null) {
harvestRow.setColumnNull("last_harvested"); harvestRow.setColumnNull("last_harvested");
} else { } else {
harvestRow.setColumn("last_harvested", date); harvestRow.setColumn("last_harvested", date);
} }
if (message == null || message.length() == 0) { if (message == null || message.length() == 0) {
harvestRow.setColumnNull("harvest_message"); harvestRow.setColumnNull("harvest_message");
} else { } else {
harvestRow.setColumn("harvest_message", message); harvestRow.setColumn("harvest_message", message);
} }
} }
public void setHarvestMessage(String message) { public void setHarvestMessage(String message) {
if (message == null || message.length() == 0) { if (message == null || message.length() == 0) {
harvestRow.setColumnNull("harvest_message"); harvestRow.setColumnNull("harvest_message");
} else { } else {
harvestRow.setColumn("harvest_message", message); harvestRow.setColumn("harvest_message", message);
} }
} }
public void setHarvestStartTime(Date date) { public void setHarvestStartTime(Date date) {
if (date == null) { if (date == null) {
harvestRow.setColumnNull("harvest_start_time"); harvestRow.setColumnNull("harvest_start_time");
} else { } else {
harvestRow.setColumn("harvest_start_time", date); harvestRow.setColumn("harvest_start_time", date);
} }
} }
/* Getting for the appropriate harvesting-related columns */ /* Getting for the appropriate harvesting-related columns */
public int getCollectionId() { public int getCollectionId() {
return harvestRow.getIntColumn("collection_id"); return harvestRow.getIntColumn("collection_id");
} }
public int getHarvestType() { public int getHarvestType() {
return harvestRow.getIntColumn("harvest_type"); return harvestRow.getIntColumn("harvest_type");
} }
public int getHarvestStatus() { public int getHarvestStatus() {
return harvestRow.getIntColumn("harvest_status"); return harvestRow.getIntColumn("harvest_status");
} }
public String getOaiSource() { public String getOaiSource() {
return harvestRow.getStringColumn("oai_source"); return harvestRow.getStringColumn("oai_source");
} }
public String getOaiSetId() { public String getOaiSetId() {
return harvestRow.getStringColumn("oai_set_id"); return harvestRow.getStringColumn("oai_set_id");
} }
public String getHarvestMetadataConfig() { public String getHarvestMetadataConfig() {
return harvestRow.getStringColumn("metadata_config_id"); return harvestRow.getStringColumn("metadata_config_id");
} }
public String getHarvestMessage() { public String getHarvestMessage() {
return harvestRow.getStringColumn("harvest_message"); return harvestRow.getStringColumn("harvest_message");
} }
public Date getHarvestDate() { public Date getHarvestDate() {
return harvestRow.getDateColumn("last_harvested"); return harvestRow.getDateColumn("last_harvested");
} }
public Date getHarvestStartTime() { public Date getHarvestStartTime() {
return harvestRow.getDateColumn("harvest_start_time"); return harvestRow.getDateColumn("harvest_start_time");
} }
public void delete() throws SQLException { public void delete() throws SQLException {
DatabaseManager.delete(context, harvestRow); DatabaseManager.delete(context, harvestRow);
} }
public void update() throws SQLException, IOException, AuthorizeException public void update() throws SQLException, IOException, AuthorizeException
{ {
DatabaseManager.update(context, harvestRow); DatabaseManager.update(context, harvestRow);
} }
} }

View File

@@ -1,171 +1,171 @@
/** /**
* The contents of this file are subject to the license and copyright * 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 * detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at * tree and available online at
* *
* http://www.dspace.org/license/ * http://www.dspace.org/license/
*/ */
package org.dspace.harvest; package org.dspace.harvest;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Date; import java.util.Date;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.storage.rdbms.DatabaseManager; import org.dspace.storage.rdbms.DatabaseManager;
import org.dspace.storage.rdbms.TableRow; import org.dspace.storage.rdbms.TableRow;
import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.storage.rdbms.TableRowIterator;
/** /**
* @author Alexey Maslov * @author Alexey Maslov
*/ */
public class HarvestedItem public class HarvestedItem
{ {
private Context context; private Context context;
private TableRow harvestRow; private TableRow harvestRow;
HarvestedItem(Context c, TableRow row) HarvestedItem(Context c, TableRow row)
{ {
context = c; context = c;
harvestRow = row; harvestRow = row;
} }
public static void exists(Context c) throws SQLException { public static void exists(Context c) throws SQLException {
DatabaseManager.queryTable(c, "harvested_item", "SELECT COUNT(*) FROM harvested_item"); DatabaseManager.queryTable(c, "harvested_item", "SELECT COUNT(*) FROM harvested_item");
} }
/** /**
* Find the harvest parameters corresponding to the specified DSpace item * Find the harvest parameters corresponding to the specified DSpace item
* @return a HarvestedItem object corresponding to this item, null if not found. * @return a HarvestedItem object corresponding to this item, null if not found.
*/ */
public static HarvestedItem find(Context c, int item_id) throws SQLException public static HarvestedItem find(Context c, int item_id) throws SQLException
{ {
TableRow row = DatabaseManager.findByUnique(c, "harvested_item", "item_id", item_id); TableRow row = DatabaseManager.findByUnique(c, "harvested_item", "item_id", item_id);
if (row == null) { if (row == null) {
return null; return null;
} }
return new HarvestedItem(c, row); 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; * 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. * Retrieve a DSpace Item that corresponds to this particular combination of owning collection and OAI ID.
* @param context * @param context
* @param itemOaiID the string used by the OAI-PMH provider to identify the item * @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 * @param collectionID id of the local collection that the item should be found in
* @return DSpace Item or null if no item was found * @return DSpace Item or null if no item was found
*/ */
public static Item getItemByOAIId(Context context, String itemOaiID, int collectionID) throws SQLException 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 * 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 * 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. * provider but not to the harvester.
*/ */
Item resolvedItem = null; Item resolvedItem = null;
TableRowIterator tri = null; TableRowIterator tri = null;
final String selectItemFromOaiId = "SELECT dsi.item_id FROM " + 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=?) " + "(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=?"; "dsi JOIN collection ON dsi.owning_collection=collection.collection_id WHERE collection.collection_id=?";
try try
{ {
tri = DatabaseManager.query(context, selectItemFromOaiId, itemOaiID, collectionID); tri = DatabaseManager.query(context, selectItemFromOaiId, itemOaiID, collectionID);
if (tri.hasNext()) if (tri.hasNext())
{ {
TableRow row = tri.next(); TableRow row = tri.next();
int itemID = row.getIntColumn("item_id"); int itemID = row.getIntColumn("item_id");
resolvedItem = Item.find(context, itemID); resolvedItem = Item.find(context, itemID);
} }
else { else {
return null; return null;
} }
} }
finally { finally {
if (tri != null) if (tri != null)
{ {
tri.close(); tri.close();
} }
} }
return resolvedItem; return resolvedItem;
} }
/** /**
* Create a new harvested item row for a specified item id. * Create a new harvested item row for a specified item id.
* @return a new HarvestedItem object * @return a new HarvestedItem object
*/ */
public static HarvestedItem create(Context c, int itemId, String itemOAIid) throws SQLException { public static HarvestedItem create(Context c, int itemId, String itemOAIid) throws SQLException {
TableRow row = DatabaseManager.row("harvested_item"); TableRow row = DatabaseManager.row("harvested_item");
row.setColumn("item_id", itemId); row.setColumn("item_id", itemId);
row.setColumn("oai_id", itemOAIid); row.setColumn("oai_id", itemOAIid);
DatabaseManager.insert(c, row); DatabaseManager.insert(c, row);
return new HarvestedItem(c, row); return new HarvestedItem(c, row);
} }
public String getItemID() public String getItemID()
{ {
String oai_id = harvestRow.getStringColumn("item_id"); String oai_id = harvestRow.getStringColumn("item_id");
return oai_id; return oai_id;
} }
/** /**
* Get the oai_id associated with this item * Get the oai_id associated with this item
*/ */
public String getOaiID() public String getOaiID()
{ {
String oai_id = harvestRow.getStringColumn("oai_id"); String oai_id = harvestRow.getStringColumn("oai_id");
return oai_id; return oai_id;
} }
/** /**
* Set the oai_id associated with this item * Set the oai_id associated with this item
*/ */
public void setOaiID(String itemOaiID) public void setOaiID(String itemOaiID)
{ {
harvestRow.setColumn("oai_id",itemOaiID); harvestRow.setColumn("oai_id",itemOaiID);
return; return;
} }
public void setHarvestDate(Date date) { public void setHarvestDate(Date date) {
if (date == null) { if (date == null) {
date = new Date(); date = new Date();
} }
harvestRow.setColumn("last_harvested", date); harvestRow.setColumn("last_harvested", date);
} }
public Date getHarvestDate() { public Date getHarvestDate() {
return harvestRow.getDateColumn("last_harvested"); return harvestRow.getDateColumn("last_harvested");
} }
public void delete() throws SQLException { public void delete() throws SQLException {
DatabaseManager.delete(context, harvestRow); DatabaseManager.delete(context, harvestRow);
} }
public void update() throws SQLException, IOException, AuthorizeException { public void update() throws SQLException, IOException, AuthorizeException {
DatabaseManager.update(context, harvestRow); DatabaseManager.update(context, harvestRow);
} }
} }

View File

@@ -1102,6 +1102,7 @@ public class DatabaseManager
break; break;
case Types.INTEGER: case Types.INTEGER:
case Types.NUMERIC:
if (isOracle) if (isOracle)
{ {
long longValue = results.getLong(i); long longValue = results.getLong(i);
@@ -1120,7 +1121,6 @@ public class DatabaseManager
} }
break; break;
case Types.NUMERIC:
case Types.DECIMAL: case Types.DECIMAL:
case Types.BIGINT: case Types.BIGINT:
row.setColumn(name, results.getLong(i)); row.setColumn(name, results.getLong(i));

View File

@@ -5,6 +5,7 @@
# #
# http://www.dspace.org/license/ # http://www.dspace.org/license/
# #
browse.page-title = Browsing DSpace browse.page-title = Browsing DSpace
browse.et-al = et al 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.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.text2 = If you think you should have authorization, please feel free to contact the DSpace administrators:
jsp.error.authorize.title = Authorization Required 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.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.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. 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); 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. * 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 # which DSpace will construct the deposit location urls for
# collections. # 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 # In the event that you are not deploying DSpace as the ROOT
# application in the servlet container, this will generate # 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 # URL from which DSpace will construct the service document
# location urls for the site, and for individual collections # 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 # In the event that you are not deploying DSpace as the ROOT
# application in the servlet container, this will generate # 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 # which DSpace will use to construct the media link urls
# for items which are deposited via sword # 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 # In the event that you are not deploying DSpace as the ROOT
# application in the servlet container, this will generate # application in the servlet container, this will generate

View File

@@ -584,4 +584,18 @@
<scope_note>Nature or genre of content.</scope_note> <scope_note>Nature or genre of content.</scope_note>
</dc-type> </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> </dspace-dc-types>

View File

@@ -1,124 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <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> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-discovery-provider</artifactId> <artifactId>dspace-discovery-provider</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<name>DSpace Discovery :: Discovery Provider Library</name> <name>DSpace Discovery :: Discovery Provider Library</name>
<description> <description>
Build Information Build Information
$Id: pom.xml 5367 2010-09-30 00:30:11Z mdiggory $ $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 $ $URL: https://scm.dspace.org/svn/repo/modules/dspace-discovery/trunk/provider/pom.xml $
</description> </description>
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>discovery-modules</artifactId> <artifactId>discovery-modules</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
</parent> <relativePath>..</relativePath>
</parent>
<dependencies>
<properties>
<dependency> <!-- This is the path to the root [dspace-src] directory. -->
<groupId>org.dspace</groupId> <root.basedir>${basedir}/../..</root.basedir>
<artifactId>dspace-api</artifactId> </properties>
</dependency>
<dependencies>
<dependency>
<groupId>commons-httpclient</groupId> <dependency>
<artifactId>commons-httpclient</artifactId> <groupId>org.dspace</groupId>
</dependency> <artifactId>dspace-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId> <dependency>
<artifactId>servlet-api</artifactId> <groupId>commons-httpclient</groupId>
<scope>provided</scope> <artifactId>commons-httpclient</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.solr</groupId> <groupId>javax.servlet</groupId>
<artifactId>solr-solrj</artifactId> <artifactId>servlet-api</artifactId>
<version>1.4.1</version> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>org.apache.solr</groupId>
<artifactId>commons-io</artifactId> <artifactId>solr-solrj</artifactId>
<scope>provided</scope> <version>1.4.1</version>
</dependency> </dependency>
</dependencies> <dependency>
<groupId>commons-io</groupId>
<build> <artifactId>commons-io</artifactId>
<plugins> <scope>provided</scope>
<plugin> </dependency>
<groupId>org.apache.cocoon</groupId>
<artifactId>cocoon-maven-plugin</artifactId> </dependencies>
<version>1.0.0-M2</version>
<executions> <build>
<execution> <plugins>
<id>prepare</id> <plugin>
<phase>compile</phase> <groupId>org.apache.cocoon</groupId>
<goals> <artifactId>cocoon-maven-plugin</artifactId>
<goal>prepare</goal> <version>1.0.0-M2</version>
</goals> <executions>
</execution> <execution>
</executions> <id>prepare</id>
</plugin> <phase>compile</phase>
<plugin> <goals>
<groupId>org.mortbay.jetty</groupId> <goal>prepare</goal>
<artifactId>maven-jetty-plugin</artifactId> </goals>
<version>6.1.7</version> </execution>
<configuration> </executions>
<connectors> </plugin>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <plugin>
<port>8888</port> <groupId>org.mortbay.jetty</groupId>
<maxIdleTime>30000</maxIdleTime> <artifactId>maven-jetty-plugin</artifactId>
</connector> <version>6.1.7</version>
</connectors> <configuration>
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory> <connectors>
<contextPath>/</contextPath> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<systemProperties> <port>8888</port>
<systemProperty> <maxIdleTime>30000</maxIdleTime>
<name>org.apache.cocoon.mode</name> </connector>
<value>dev</value> </connectors>
</systemProperty> <webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
</systemProperties> <contextPath>/</contextPath>
</configuration> <systemProperties>
</plugin> <systemProperty>
<!-- <name>org.apache.cocoon.mode</name>
<plugin> <value>dev</value>
<artifactId>maven-jar-plugin</artifactId> </systemProperty>
<version>2.1</version> </systemProperties>
<configuration> </configuration>
<archive> </plugin>
<manifestEntries> <!--
<Cocoon-Block-Name>${pom.artifactId}</Cocoon-Block-Name> <plugin>
</manifestEntries> <artifactId>maven-jar-plugin</artifactId>
</archive> <version>2.1</version>
</configuration> <configuration>
</plugin> <archive>
--> <manifestEntries>
<plugin> <Cocoon-Block-Name>${pom.artifactId}</Cocoon-Block-Name>
<artifactId>maven-eclipse-plugin</artifactId> </manifestEntries>
<version>2.5</version> </archive>
</plugin> </configuration>
</plugins> </plugin>
</build> -->
<plugin>
<!-- <artifactId>maven-eclipse-plugin</artifactId>
The Subversion repository location is used by Continuum to update <version>2.5</version>
against when changes have occured, this spawns a new build cycle </plugin>
and releases snapshots into the snapshot repository below. </plugins>
--> </build>
<scm>
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-provider</connection> </project>
<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>

View File

@@ -44,6 +44,8 @@ public class SearchUtils {
private static List<String> dateIndexableFields = new ArrayList<String>(); private static List<String> dateIndexableFields = new ArrayList<String>();
public static final String FILTER_SEPARATOR = "|||";
static { static {
log.debug("loading configuration"); log.debug("loading configuration");
@@ -190,6 +192,20 @@ public class SearchUtils {
return dateIndexableFields; 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 { public static class SolrFacetConfig {
private String facetField; private String facetField;

View File

@@ -8,6 +8,7 @@
package org.dspace.discovery; package org.dspace.discovery;
import org.apache.commons.collections.ExtendedProperties; import org.apache.commons.collections.ExtendedProperties;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.SolrQuery; 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)){ if(SearchUtils.getAllFacets().contains(field) || SearchUtils.getAllFacets().contains(unqualifiedField + "." + Item.ANY)){
//Add a special filter //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)){ if(SearchUtils.getSortFields().contains(field) && !sortFieldsAdded.contains(field)){
@@ -773,9 +777,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
readers.add(is); readers.add(is);
// Add each InputStream to the Indexed Document // Add each InputStream to the Indexed Document
// (Acts like an Append) doc.addField("fulltext", IOUtils.toString(is));
// doc.addField("default", is);
//doc.add(new Field("default", is));
log.debug(" Added BitStream: " log.debug(" Added BitStream: "
+ myBitstreams[j].getStoreNumber() + " " + myBitstreams[j].getStoreNumber() + " "

View File

@@ -1,130 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <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> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-discovery-xmlui-api</artifactId> <artifactId>dspace-discovery-xmlui-api</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<name>DSpace Discovery :: Discovery XMLUI API</name> <name>DSpace Discovery :: Discovery XMLUI API</name>
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>discovery-modules</artifactId> <artifactId>discovery-modules</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
</parent> <relativePath>..</relativePath>
</parent>
<dependencies>
<properties>
<dependency> <!-- This is the path to the root [dspace-src] directory. -->
<groupId>org.dspace</groupId> <root.basedir>${basedir}/../..</root.basedir>
<artifactId>dspace-xmlui-api</artifactId> </properties>
<exclusions>
<exclusion> <dependencies>
<artifactId>solr-solrj</artifactId>
<groupId>org.apache.solr</groupId> <dependency>
</exclusion> <groupId>org.dspace</groupId>
</exclusions> <artifactId>dspace-xmlui-api</artifactId>
</dependency> <exclusions>
<exclusion>
<!-- external --> <artifactId>solr-solrj</artifactId>
<dependency> <groupId>org.apache.solr</groupId>
<groupId>javax.servlet</groupId> </exclusion>
<artifactId>servlet-api</artifactId> </exclusions>
<scope>provided</scope> </dependency>
</dependency>
<!-- external -->
<dependency>
<dependency> <groupId>javax.servlet</groupId>
<groupId>org.dspace</groupId> <artifactId>servlet-api</artifactId>
<artifactId>dspace-discovery-provider</artifactId> <scope>provided</scope>
</dependency> </dependency>
</dependencies>
<dependency>
<build> <groupId>org.dspace</groupId>
<plugins> <artifactId>dspace-discovery-provider</artifactId>
<plugin> </dependency>
<groupId>org.apache.cocoon</groupId>
<artifactId>cocoon-maven-plugin</artifactId> </dependencies>
<executions>
<execution> <build>
<id>prepare</id> <plugins>
<phase>compile</phase> <plugin>
<goals> <groupId>org.apache.cocoon</groupId>
<goal>prepare</goal> <artifactId>cocoon-maven-plugin</artifactId>
</goals> <version>1.0.0</version>
</execution> <executions>
</executions> <execution>
</plugin> <id>prepare</id>
<!-- <phase>compile</phase>
<plugin> <goals>
<groupId>org.apache.maven.plugins</groupId> <goal>prepare</goal>
<artifactId>maven-war-plugin</artifactId> </goals>
<configuration> </execution>
<archiveClasses>false</archiveClasses> </executions>
<attachClasses>true</attachClasses> </plugin>
<classesClassifier>classes</classesClassifier> <!--
<failOnMissingWebXml>false</failOnMissingWebXml> <plugin>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes> <groupId>org.apache.maven.plugins</groupId>
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes> <artifactId>maven-war-plugin</artifactId>
</configuration> <configuration>
<executions> <archiveClasses>false</archiveClasses>
<execution> <attachClasses>true</attachClasses>
<phase>prepare-package</phase> <classesClassifier>classes</classesClassifier>
</execution> <failOnMissingWebXml>false</failOnMissingWebXml>
</executions> <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
</plugin> <warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
--> </configuration>
<plugin> <executions>
<groupId>org.mortbay.jetty</groupId> <execution>
<artifactId>maven-jetty-plugin</artifactId> <phase>prepare-package</phase>
<version>6.1.7</version> </execution>
<configuration> </executions>
<connectors> </plugin>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> -->
<port>8888</port> <plugin>
<maxIdleTime>30000</maxIdleTime> <groupId>org.mortbay.jetty</groupId>
</connector> <artifactId>maven-jetty-plugin</artifactId>
</connectors> <version>6.1.7</version>
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory> <configuration>
<contextPath>/</contextPath> <connectors>
<systemProperties> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<systemProperty> <port>8888</port>
<name>org.apache.cocoon.mode</name> <maxIdleTime>30000</maxIdleTime>
<value>dev</value> </connector>
</systemProperty> </connectors>
</systemProperties> <webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
</configuration> <contextPath>/</contextPath>
</plugin> <systemProperties>
<!-- <systemProperty>
<plugin> <name>org.apache.cocoon.mode</name>
<groupId>org.apache.maven.plugins</groupId> <value>dev</value>
<artifactId>maven-jar-plugin</artifactId> </systemProperty>
<configuration> </systemProperties>
<archive> </configuration>
<index>true</index> </plugin>
<manifestEntries> <!--
<Cocoon-Block-Name>discovery-xmlui-block</Cocoon-Block-Name> <plugin>
</manifestEntries> <groupId>org.apache.maven.plugins</groupId>
</archive> <artifactId>maven-jar-plugin</artifactId>
</configuration> <configuration>
</plugin> <archive>
--> <index>true</index>
</plugins> <manifestEntries>
</build> <Cocoon-Block-Name>discovery-xmlui-block</Cocoon-Block-Name>
</manifestEntries>
<!-- </archive>
The Subversion repository location is used by Continuum to update </configuration>
against when changes have occured, this spawns a new build cycle </plugin>
and releases snapshots into the snapshot repository below. -->
--> </plugins>
<scm> </build>
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-api</connection>
<developerConnection> </project>
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>

View File

@@ -37,7 +37,6 @@ import org.xml.sax.SAXException;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.net.URLEncoder;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@@ -386,7 +385,7 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
continue; continue;
} }
for (FacetField.Count count : facetVals) { 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()){ if(field.isDate()){
@@ -463,9 +462,12 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
if(keys != null){ if(keys != null){
while (keys.hasMoreElements()){ while (keys.hasMoreElements()){
String key = (String) keys.nextElement(); String key = (String) keys.nextElement();
if(key != null){ if(key != null && !"page".equals(key)){
paramsQuery += key + "=" + URLEncoder.encode(request.getParameter(key), "UTF-8"); String[] vals = request.getParameterValues(key);
paramsQuery += "&"; for(String paramValue : vals){
paramsQuery += key + "=" + paramValue;
paramsQuery += "&";
}
} }
} }
} }
@@ -476,7 +478,7 @@ public abstract class AbstractFiltersTransformer extends AbstractDSpaceTransform
"/discover?" + "/discover?" +
paramsQuery + paramsQuery +
"fq=" + "fq=" +
URLEncoder.encode(filterQuery, "UTF-8"), filterQuery,
displayedValue + " (" + value.getCount() + ")" 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 ); 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 = prepareDefaultFilters(getView());
this.queryArgs.setRows(1); 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","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.mindf","1");
this.queryArgs.add("mlt.mintf","1"); this.queryArgs.add("mlt.mintf","1");
this.queryArgs.setQuery("handle:" + dso.getHandle()); 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 //No use in selecting the same filter twice
if(filterQueries.contains(filterQuery)){ if(filterQueries.contains(filterQuery)){
cell.addContent(displayedValue + " (" + value.getCount() + ")"); cell.addContent(SearchUtils.getFilterQueryDisplay(displayedValue) + " (" + value.getCount() + ")");
} else { } else {
//Add the basics //Add the basics
Map<String, String> urlParams = new HashMap<String, String>(); Map<String, String> urlParams = new HashMap<String, String>();
@@ -567,8 +567,8 @@ public class SearchFacetFilter extends AbstractDSpaceTransformer implements Cach
//Add already existing filter queries //Add already existing filter queries
url = addFilterQueriesToUrl(url); url = addFilterQueriesToUrl(url);
//Last add the current filter query //Last add the current filter query
url += "&fq=" + URLEncoder.encode(filterQuery, "UTF-8"); url += "&fq=" + filterQuery;
cell.addXref(url, displayedValue + " (" + value.getCount() + ")" 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"); // String searchUrl = SearchUtils.getConfig().getString("solr.search.server");
// if(searchUrl != null && !searchUrl.endsWith("/")) // if(searchUrl != null && !searchUrl.endsWith("/"))
// searchUrl += "/"; // 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("solr-search-url").setValue(searchUrl);
search.addHidden("contextpath").setValue(contextPath); 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")){ if(field.equals("location.comm") || field.equals("location.coll")){
//We have a community/collection, resolve it to a dspaceObject //We have a community/collection, resolve it to a dspaceObject
value = SolrServiceImpl.locationToName(context, field, value); value = SolrServiceImpl.locationToName(context, field, value);
} else
if(field.endsWith("_filter")){
value = SearchUtils.getFilterQueryDisplay(value);
} }
//Check for a range query //Check for a range query
Pattern pattern = Pattern.compile("\\[(.*? TO .*?)\\]"); Pattern pattern = Pattern.compile("\\[(.*? TO .*?)\\]");

View File

@@ -1,155 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Licensed to the Apache Software Foundation (ASF) under one or more Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership. this work for additional information regarding copyright ownership.
The ASF licenses this file to you under the Apache License, Version 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 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 with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless required by http://www.apache.org/licenses/LICENSE-2.0 Unless required by
applicable law or agreed to in writing, software distributed under the applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for CONDITIONS OF ANY KIND, either express or implied. See the License for
the specific language governing permissions and limitations under the the specific language governing permissions and limitations under the
License. License.
--> -->
<!-- $Id: pom.xml 4739 2010-02-04 16:53:55Z benbosman $ --> <!-- $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"> <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> <modelVersion>4.0.0</modelVersion>
<packaging>war</packaging> <packaging>war</packaging>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-discovery-xmlui-webapp</artifactId> <artifactId>dspace-discovery-xmlui-webapp</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<name>DSpace Discovery :: Discovery XMLUI Webapp</name> <name>DSpace Discovery :: Discovery XMLUI Webapp</name>
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>discovery-modules</artifactId> <artifactId>discovery-modules</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
</parent> <relativePath>..</relativePath>
</parent>
<dependencies>
<properties>
<dependency> <!-- This is the path to the root [dspace-src] directory. -->
<groupId>org.dspace</groupId> <root.basedir>${basedir}/../..</root.basedir>
<artifactId>dspace-xmlui-api</artifactId> </properties>
<exclusions>
<exclusion> <dependencies>
<artifactId>solr-solrj</artifactId>
<groupId>org.apache.solr</groupId> <dependency>
</exclusion> <groupId>org.dspace</groupId>
</exclusions> <artifactId>dspace-xmlui-api</artifactId>
</dependency> <exclusions>
<exclusion>
<dependency> <artifactId>solr-solrj</artifactId>
<groupId>org.dspace</groupId> <groupId>org.apache.solr</groupId>
<artifactId>dspace-discovery-xmlui-api</artifactId> </exclusion>
<version>1.7.1-SNAPSHOT</version> </exclusions>
</dependency> </dependency>
<!-- external --> <dependency>
<dependency> <groupId>org.dspace</groupId>
<groupId>javax.servlet</groupId> <artifactId>dspace-discovery-xmlui-api</artifactId>
<artifactId>servlet-api</artifactId> <version>1.7.3</version>
<scope>provided</scope> </dependency>
</dependency>
<!-- external -->
<dependency>
<groupId>javax.servlet</groupId>
</dependencies> <artifactId>servlet-api</artifactId>
<scope>provided</scope>
<build> </dependency>
<plugins>
<plugin>
<groupId>org.apache.cocoon</groupId>
<artifactId>cocoon-maven-plugin</artifactId> </dependencies>
<executions>
<execution> <build>
<id>prepare</id> <plugins>
<phase>compile</phase> <plugin>
<goals> <groupId>org.apache.cocoon</groupId>
<goal>prepare</goal> <artifactId>cocoon-maven-plugin</artifactId>
</goals> <version>1.0.0</version>
</execution> <executions>
</executions> <execution>
</plugin> <id>prepare</id>
<plugin> <phase>compile</phase>
<groupId>org.apache.maven.plugins</groupId> <goals>
<artifactId>maven-war-plugin</artifactId> <goal>prepare</goal>
<configuration> </goals>
<archiveClasses>false</archiveClasses> </execution>
<attachClasses>true</attachClasses> </executions>
<classesClassifier>classes</classesClassifier> </plugin>
<failOnMissingWebXml>false</failOnMissingWebXml> <plugin>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes> <groupId>org.apache.maven.plugins</groupId>
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes> <artifactId>maven-war-plugin</artifactId>
<webResources> <configuration>
<resource> <archiveClasses>false</archiveClasses>
<filtering>true</filtering> <attachClasses>true</attachClasses>
<directory>${basedir}/src/main/webapp</directory> <classesClassifier>classes</classesClassifier>
<includes> <failOnMissingWebXml>false</failOnMissingWebXml>
<include>WEB-INF/web.xml</include> <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
</includes> <warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
</resource> <webResources>
</webResources> <resource>
</configuration> <filtering>true</filtering>
<executions> <directory>${basedir}/src/main/webapp</directory>
<execution> <includes>
<phase>prepare-package</phase> <include>WEB-INF/web.xml</include>
</execution> </includes>
</executions> </resource>
</plugin> </webResources>
<plugin> </configuration>
<groupId>org.mortbay.jetty</groupId> <executions>
<artifactId>maven-jetty-plugin</artifactId> <execution>
<version>6.1.7</version> <phase>prepare-package</phase>
<configuration> </execution>
<connectors> </executions>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> </plugin>
<port>8888</port> <plugin>
<maxIdleTime>30000</maxIdleTime> <groupId>org.mortbay.jetty</groupId>
</connector> <artifactId>maven-jetty-plugin</artifactId>
</connectors> <version>6.1.7</version>
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory> <configuration>
<contextPath>/</contextPath> <connectors>
<systemProperties> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<systemProperty> <port>8888</port>
<name>org.apache.cocoon.mode</name> <maxIdleTime>30000</maxIdleTime>
<value>dev</value> </connector>
</systemProperty> </connectors>
</systemProperties> <webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
</configuration> <contextPath>/</contextPath>
</plugin> <systemProperties>
<!-- <systemProperty>
<plugin> <name>org.apache.cocoon.mode</name>
<groupId>org.apache.maven.plugins</groupId> <value>dev</value>
<artifactId>maven-jar-plugin</artifactId> </systemProperty>
<configuration> </systemProperties>
<archive> </configuration>
<index>true</index> </plugin>
<manifestEntries> <plugin>
<Cocoon-Block-Name>discovery-xmlui-block</Cocoon-Block-Name> <groupId>com.mycila.maven-license-plugin</groupId>
</manifestEntries> <artifactId>maven-license-plugin</artifactId>
</archive> <configuration>
</configuration> <!--Exclude license check for Discovery files which don't need it-->
</plugin> <excludes>
--> <exclude>**/COPYRIGHT.txt</exclude>
</plugins> <exclude>**/LICENSE.txt</exclude>
</build> <exclude>**/*.LICENSE</exclude>
<exclude>**/jquery*</exclude>
<!-- <exclude>**/jquery/*</exclude>
The Subversion repository location is used by Continuum to update <exclude>**/*.xmap</exclude>
against when changes have occured, this spawns a new build cycle </excludes>
and releases snapshots into the snapshot repository below. </configuration>
--> </plugin>
<scm> <!--
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-webapp</connection> <plugin>
<developerConnection> <groupId>org.apache.maven.plugins</groupId>
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-webapp <artifactId>maven-jar-plugin</artifactId>
</developerConnection> <configuration>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery/dspace-discovery-xmlui-webapp</url> <archive>
</scm> <index>true</index>
<manifestEntries>
</project> <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"?> <?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"> <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> <modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging> <packaging>pom</packaging>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>discovery-modules</artifactId> <artifactId>discovery-modules</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<name>DSpace Discovery :: Modules</name> <name>DSpace Discovery :: Modules</name>
<parent> <parent>
<artifactId>dspace-parent</artifactId> <artifactId>dspace-parent</artifactId>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
</parent> <relativePath>..</relativePath>
</parent>
<modules>
<module>dspace-discovery-provider</module> <properties>
<module>dspace-discovery-xmlui-api</module> <!-- This is the path to the root [dspace-src] directory. -->
<module>dspace-discovery-xmlui-webapp</module> <root.basedir>${basedir}/..</root.basedir>
</modules> </properties>
<build> <modules>
<plugins> <module>dspace-discovery-provider</module>
<plugin> <module>dspace-discovery-xmlui-api</module>
<groupId>org.mortbay.jetty</groupId> <module>dspace-discovery-xmlui-webapp</module>
<artifactId>maven-jetty-plugin</artifactId> </modules>
<version>6.1.7</version>
<configuration> <build>
<connectors> <plugins>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <plugin>
<port>8888</port> <groupId>org.mortbay.jetty</groupId>
<maxIdleTime>30000</maxIdleTime> <artifactId>maven-jetty-plugin</artifactId>
</connector> <version>6.1.7</version>
</connectors> <configuration>
<webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory> <connectors>
<contextPath>/</contextPath> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<systemProperties> <port>8888</port>
<systemProperty> <maxIdleTime>30000</maxIdleTime>
<name>org.apache.cocoon.mode</name> </connector>
<value>dev</value> </connectors>
</systemProperty> <webAppSourceDirectory>${project.build.directory}/rcl/webapp</webAppSourceDirectory>
</systemProperties> <contextPath>/</contextPath>
</configuration> <systemProperties>
</plugin> <systemProperty>
</plugins> <name>org.apache.cocoon.mode</name>
</build> <value>dev</value>
</systemProperty>
<!-- </systemProperties>
The Subversion repository location is used by Continuum to update </configuration>
against when changes have occured, this spawns a new build cycle </plugin>
and releases snapshots into the snapshot repository below. </plugins>
--> </build>
<scm>
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery</connection> <issueManagement>
<developerConnection> <system>JIRA</system>
scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery <url>http://jira.dspace.org/jira/browse/DISCOVERY</url>
</developerConnection> </issueManagement>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-discovery</url>
</scm> </project>
<issueManagement>
<system>JIRA</system>
<url>http://jira.dspace.org/jira/browse/DISCOVERY</url>
</issueManagement>
</project>

View File

@@ -14,19 +14,14 @@
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-jspui</artifactId> <artifactId>dspace-jspui</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<!-- <properties>
The Subversion repository location is used by Continuum to update against <!-- This is the path to the root [dspace-src] directory. -->
when changes have occured, this spawns a new build cycle and releases snapshots <root.basedir>${basedir}/../..</root.basedir>
into the snapshot repository below. </properties>
-->
<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>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -80,4 +75,4 @@
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -98,7 +98,7 @@ public class BrowserServlet extends AbstractBrowserServlet
throws ServletException, IOException, SQLException, throws ServletException, IOException, SQLException,
AuthorizeException 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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.app.util.SubmissionInfo; import org.dspace.app.util.SubmissionInfo;
@@ -219,7 +220,14 @@ public class SubmissionController extends DSpaceServlet
if ((contentType != null) if ((contentType != null)
&& (contentType.indexOf("multipart/form-data") != -1)) && (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) //also, upload any files and save their contents to Request (for later processing by UploadStep)
uploadFiles(context, request); uploadFiles(context, request);
@@ -1350,7 +1358,7 @@ public class SubmissionController extends DSpaceServlet
* if there are no more pages in this step * if there are no more pages in this step
*/ */
private HttpServletRequest wrapMultipartRequest(HttpServletRequest request) private HttpServletRequest wrapMultipartRequest(HttpServletRequest request)
throws ServletException throws ServletException, FileSizeLimitExceededException
{ {
HttpServletRequest wrappedRequest; HttpServletRequest wrappedRequest;
@@ -1370,6 +1378,10 @@ public class SubmissionController extends DSpaceServlet
return request; return request;
} }
} }
catch (FileSizeLimitExceededException e)
{
throw new FileSizeLimitExceededException(e.getMessage(),e.getActualSize(),e.getPermittedSize());
}
catch (Exception e) catch (Exception e)
{ {
throw new ServletException(e); throw new ServletException(e);

View File

@@ -18,6 +18,7 @@ import java.util.List;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@@ -457,88 +458,83 @@ public class CollectionWizardServlet extends DSpaceServlet
HttpServletResponse response) throws SQLException, HttpServletResponse response) throws SQLException,
ServletException, IOException, AuthorizeException ServletException, IOException, AuthorizeException
{ {
// Wrap multipart request to get the submission info try {
FileUploadRequest wrapper = new FileUploadRequest(request); // Wrap multipart request to get the submission info
FileUploadRequest wrapper = new FileUploadRequest(request);
Collection collection = Collection.find(context, UIUtil Collection collection = Collection.find(context, UIUtil.getIntParameter(wrapper, "collection_id"));
.getIntParameter(wrapper, "collection_id")); if (collection == null)
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)
{ {
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); File temp = wrapper.getFile("file");
logoBS.setSource(wrapper.getFilesystemName("file"));
// Identify the format if (temp != null)
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"); // 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.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.util.AuthorizeUtil;
@@ -893,92 +894,93 @@ public class EditCommunitiesServlet extends DSpaceServlet
HttpServletResponse response) throws ServletException, IOException, HttpServletResponse response) throws ServletException, IOException,
SQLException, AuthorizeException SQLException, AuthorizeException
{ {
// Wrap multipart request to get the submission info try {
FileUploadRequest wrapper = new FileUploadRequest(request); // 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( // Read the temp file as logo
wrapper, "community_id")); InputStream is = new BufferedInputStream(new FileInputStream(temp));
Collection collection = Collection.find(context, UIUtil Bitstream logoBS;
.getIntParameter(wrapper, "collection_id"));
File temp = wrapper.getFile("file"); if (collection == null)
{
logoBS = community.setLogo(is);
}
else
{
logoBS = collection.setLogo(is);
}
// Read the temp file as logo // Strip all but the last filename. It would be nice
InputStream is = new BufferedInputStream(new FileInputStream(temp)); // to know which OS the file came from.
Bitstream logoBS; 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.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.app.util.AuthorizeUtil; import org.dspace.app.util.AuthorizeUtil;
@@ -766,77 +767,80 @@ public class EditItemServlet extends DSpaceServlet
throws ServletException, IOException, SQLException, throws ServletException, IOException, SQLException,
AuthorizeException AuthorizeException
{ {
// Wrap multipart request to get the submission info try {
FileUploadRequest wrapper = new FileUploadRequest(request); // Wrap multipart request to get the submission info
Bitstream b = null; 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, // Read the temp file as logo
"item_id")); 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 // do we already have an ORIGINAL bundle?
InputStream is = new BufferedInputStream(new FileInputStream(temp)); Bundle[] bundles = item.getBundles("ORIGINAL");
// now check to see if person can edit item if (bundles.length < 1)
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)
{ {
Bundle bnd = b.getBundles()[0]; // set bundle's name to ORIGINAL
bnd.inheritCollectionDefaultPolicies(owningCollection); 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 log.warn("Upload exceeded upload.max");
b = bundles[0].createBitstream(is); 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"); 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 javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.fileupload.FileItem; 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.servlet.ServletFileUpload;
import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.dspace.core.ConfigurationManager; import org.dspace.core.ConfigurationManager;
@@ -47,7 +48,7 @@ public class FileUploadRequest extends HttpServletRequestWrapper
* @param req * @param req
* the original request * the original request
*/ */
public FileUploadRequest(HttpServletRequest req) throws IOException public FileUploadRequest(HttpServletRequest req) throws IOException, FileSizeLimitExceededException
{ {
super(req); super(req);
@@ -90,6 +91,16 @@ public class FileUploadRequest extends HttpServletRequestWrapper
} }
catch (Exception e) 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); throw new IOException(e.getMessage(), e);
} }
} }
@@ -183,4 +194,4 @@ public class FileUploadRequest extends HttpServletRequestWrapper
} }
return filename; return filename;
} }
} }

View File

@@ -142,4 +142,26 @@ public class JSPManager
showJSP(request, response, "/error/invalid-id.jsp"); 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> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-jspui</artifactId> <artifactId>dspace-jspui</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<!-- <properties>
The Subversion repository location is used by Continuum to update against <!-- This is the path to the root [dspace-src] directory. -->
when changes have occured, this spawns a new build cycle and releases snapshots <root.basedir>${basedir}/../..</root.basedir>
into the snapshot repository below. </properties>
-->
<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>
<build> <build>
<plugins> <plugins>
@@ -53,6 +48,18 @@
<phase>prepare-package</phase> <phase>prepare-package</phase>
</execution> </execution>
</executions> </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> </plugin>
</plugins> </plugins>
</build> </build>

View File

@@ -27,6 +27,7 @@
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %> <%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="org.dspace.core.Utils" %>
<% <%
EPerson[] epeople = EPerson[] epeople =
@@ -115,10 +116,10 @@
<%= (e.getEmail() == null ? "" : e.getEmail()) %> <%= (e.getEmail() == null ? "" : e.getEmail()) %>
</td> </td>
<td headers="t3" class="<%= row %>RowOddCol"> <td headers="t3" class="<%= row %>RowOddCol">
<%= (e.getLastName() == null ? "" : e.getLastName()) %> <%= (e.getLastName() == null ? "" : Utils.addEntities(e.getLastName())) %>
</td> </td>
<td headers="t4" class="<%= row %>RowEvenCol"> <td headers="t4" class="<%= row %>RowEvenCol">
<%= (e.getFirstName() == null ? "" : e.getFirstName()) %> <%= (e.getFirstName() == null ? "" : Utils.addEntities(e.getFirstName())) %>
</td> </td>
<td headers="t5" class="<%= row %>RowOddCol" align="center"> <td headers="t5" class="<%= row %>RowOddCol" align="center">
<%= e.canLogIn() ? "yes" : "no" %> <%= e.canLogIn() ? "yes" : "no" %>
@@ -130,7 +131,7 @@
<%= e.getSelfRegistered() ? "yes" : "no" %> <%= e.getSelfRegistered() ? "yes" : "no" %>
</td> </td>
<td headers="t8" class="<%= row %>RowEvenCol"> <td headers="t8" class="<%= row %>RowEvenCol">
<%= (e.getMetadata("phone") == null ? "" : e.getMetadata("phone")) %> <%= (e.getMetadata("phone") == null ? "" : Utils.addEntities(e.getMetadata("phone"))) %>
</td> </td>
<td headers="t9" class="<%= row %>RowOddCol"> <td headers="t9" class="<%= row %>RowOddCol">
<input type="hidden" name="eperson_id" value="<%= e.getID() %>"/> <input type="hidden" name="eperson_id" value="<%= e.getID() %>"/>

View File

@@ -20,6 +20,7 @@
prefix="fmt" %> prefix="fmt" %>
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="org.dspace.core.Utils" %>
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %> <%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
@@ -32,9 +33,9 @@
parenttitlekey="jsp.administer" parenttitlekey="jsp.administer"
parentlink="/dspace-admin"> 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"> <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:param><%= eperson.getEmail() %></fmt:param>
</fmt:message></h1> </fmt:message></h1>

View File

@@ -28,11 +28,12 @@
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="java.util.List" %> <%@ page import="java.util.List" %>
<%@ page import="java.util.Iterator" %> <%@ page import="java.util.Iterator" %>
<%@ page import="org.dspace.core.Utils" %>
<% <%
EPerson eperson = (EPerson) request.getAttribute("eperson"); EPerson eperson = (EPerson) request.getAttribute("eperson");
List tableList = (List) request.getAttribute("tableList"); List tableList = (List) request.getAttribute("tableList");
String fullName = eperson.getFullName(); String fullName = Utils.addEntities(eperson.getFullName());
Iterator tableIt = tableList.iterator(); Iterator tableIt = tableList.iterator();
%> %>

View File

@@ -28,6 +28,7 @@
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="org.dspace.eperson.Group" %> <%@ page import="org.dspace.eperson.Group" %>
<%@ page import="org.dspace.content.WorkspaceItem" %> <%@ page import="org.dspace.content.WorkspaceItem" %>
<%@ page import="org.dspace.core.Utils" %>
<% <%
// get item and group out of the request // get item and group out of the request
@@ -75,7 +76,7 @@
<br/><br/> <br/><br/>
<strong><fmt:message key="jsp.dspace-admin.supervise-confirm-remove.authorheader"/></strong>: <strong><fmt:message key="jsp.dspace-admin.supervise-confirm-remove.authorheader"/></strong>:
<br/> <br/>
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a> <a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
<br/><br/> <br/><br/>
<strong><fmt:message key="jsp.dspace-admin.supervise-confirm-remove.supervisorgroupheader"/></strong>: <strong><fmt:message key="jsp.dspace-admin.supervise-confirm-remove.supervisorgroupheader"/></strong>:
<br/> <br/>

View File

@@ -28,6 +28,7 @@
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="org.dspace.eperson.Group" %> <%@ page import="org.dspace.eperson.Group" %>
<%@ page import="org.dspace.eperson.Supervisor" %> <%@ page import="org.dspace.eperson.Supervisor" %>
<%@ page import="org.dspace.core.Utils" %>
<% <%
// get objects from request // get objects from request
@@ -109,7 +110,7 @@
<%= workspaceItems[i].getID() %> <%= workspaceItems[i].getID() %>
</td> </td>
<td class="<%= row %>RowEvenCol"> <td class="<%= row %>RowEvenCol">
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a> <a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
</td> </td>
<td class="<%= row %>RowOddCol"> <td class="<%= row %>RowOddCol">
<% <%

View File

@@ -25,6 +25,7 @@
<%@ page import="org.dspace.content.SupervisedItem" %> <%@ page import="org.dspace.content.SupervisedItem" %>
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="org.dspace.eperson.Group" %> <%@ page import="org.dspace.eperson.Group" %>
<%@ page import="org.dspace.core.Utils" %>
<% <%
// get the object array out of the request // get the object array out of the request
@@ -97,7 +98,7 @@
<%= supervisors[j].getName() %> <%= supervisors[j].getName() %>
</td> </td>
<td class="<%= row %>RowOddCol"> <td class="<%= row %>RowOddCol">
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a> <a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
</td> </td>
<td class="<%= row %>RowEvenCol"> <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 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 detailed in the LICENSE and NOTICE files at the root of the source
tree and available online at tree and available online at
http://www.dspace.org/license/ http://www.dspace.org/license/
==== ====
The following icon files: The following icon files:
- book_key.png - book_key.png
- zoom.png - zoom.png
- bug.png - bug.png
are taken from are taken from
Silk icon set 1.3 Silk icon set 1.3
_________________________________________ _________________________________________
Mark James Mark James
http://www.famfamfam.com/lab/icons/silk/ http://www.famfamfam.com/lab/icons/silk/
_________________________________________ _________________________________________
This work is licensed under a This work is licensed under a
Creative Commons Attribution 2.5 License. Creative Commons Attribution 2.5 License.
[ http://creativecommons.org/licenses/by/2.5/ ] [ http://creativecommons.org/licenses/by/2.5/ ]
This means you may use it for any purpose, This means you may use it for any purpose,
and make any changes you like. and make any changes you like.
All I ask is that you include a link back All I ask is that you include a link back
to this page in your credits. to this page in your credits.
Are you using this icon set? Send me an email Are you using this icon set? Send me an email
(including a link or picture if available) to (including a link or picture if available) to
mjames@gmail.com mjames@gmail.com
Any other questions about this icon set please Any other questions about this icon set please
contact mjames@gmail.com contact mjames@gmail.com

View File

@@ -1,53 +1,53 @@
==== ====
The contents of this file are subject to the license and copyright 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 detailed in the LICENSE and NOTICE files at the root of the source
tree and available online at tree and available online at
http://www.dspace.org/license/ http://www.dspace.org/license/
==== ====
16x16 Free Application Icons 16x16 Free Application Icons
This icon set is free for use in personal and commercial projects. This icon set is free for use in personal and commercial projects.
License Agreement License Agreement
By purchasing icons from Aha-Soft, You (the purchaser) By purchasing icons from Aha-Soft, You (the purchaser)
agree to the terms of this agreement, as detailed below. agree to the terms of this agreement, as detailed below.
You may use the icons from Aha-Soft in commercial and You may use the icons from Aha-Soft in commercial and
personal design projects, software or Internet products. personal design projects, software or Internet products.
Icons can be displayed in documentation, help files, and Icons can be displayed in documentation, help files, and
advertising materials. You are free to sell and distribute advertising materials. You are free to sell and distribute
products and projects using purchased icons without further products and projects using purchased icons without further
royalty fees. royalty fees.
All icon files are provided 'as is'. Aha-Soft cannot be All icon files are provided 'as is'. Aha-Soft cannot be
held liable for any negative issues that may occur as a held liable for any negative issues that may occur as a
result of using the icons. result of using the icons.
You agree that all ownership and copyright of the icons You agree that all ownership and copyright of the icons
remains the property of Aha-Soft. You may not resell, remains the property of Aha-Soft. You may not resell,
distribute, lease, license or sub-license the icons or distribute, lease, license or sub-license the icons or
modified icons (or a subset of the icons), to any third modified icons (or a subset of the icons), to any third
party unless they are incorporated into your software or party unless they are incorporated into your software or
design products. design products.
If you have any questions regarding copyright or licensing, If you have any questions regarding copyright or licensing,
including whether another license is required for icon use including whether another license is required for icon use
within products, please contact us here: www.aha-soft.com/support.htm 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 Product page: http://www.small-icons.com/stock-icons/16x16-free-application-icons.htm
Icon Design Service Icon Design Service
We can design custom icons for you. Please find the basic information We can design custom icons for you. Please find the basic information
about ordering icons, pricing and the portfolio here: about ordering icons, pricing and the portfolio here:
www.aha-soft.com/customdev/design.htm www.aha-soft.com/customdev/design.htm
Notice Notice
Web-site small-icons.com belongs to Aha-Soft. Web-site small-icons.com belongs to Aha-Soft.
Support page: http://www.aha-soft.com/support.htm Support page: http://www.aha-soft.com/support.htm
Copyright <20> 2009 Aha-Soft. All rights reserved. Copyright <20> 2009 Aha-Soft. All rights reserved.

View File

@@ -25,7 +25,6 @@
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"
prefix="fmt" %> prefix="fmt" %>
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %> <%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %> <%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %>
@@ -78,7 +77,7 @@
<tr> <tr>
<td align="left"> <td align="left">
<h1> <h1>
<fmt:message key="jsp.mydspace"/>: <%= user.getFullName() %> <fmt:message key="jsp.mydspace"/>: <%= Utils.addEntities(user.getFullName()) %>
</h1> </h1>
</td> </td>
<td align="right" class="standard"> <td align="right" class="standard">
@@ -136,7 +135,7 @@
</td> </td>
<td headers="t2" class="<%= row %>RowEvenCol"><%= Utils.addEntities(title) %></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="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 %>RowOddCol"></td> -->
<td headers="t5" class="<%= row %>RowEvenCol"> <td headers="t5" class="<%= row %>RowEvenCol">
<form action="<%= request.getContextPath() %>/mydspace" method="post"> <form action="<%= request.getContextPath() %>/mydspace" method="post">
@@ -200,7 +199,7 @@
</td> </td>
<td headers="t7" class="<%= row %>RowEvenCol"><%= Utils.addEntities(title) %></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="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"> <td class="<%= row %>RowOddCol">
<form action="<%= request.getContextPath() %>/mydspace" method="post"> <form action="<%= request.getContextPath() %>/mydspace" method="post">
<input type="hidden" name="step" value="<%= MyDSpaceServlet.MAIN_PAGE %>" /> <input type="hidden" name="step" value="<%= MyDSpaceServlet.MAIN_PAGE %>" />
@@ -285,7 +284,7 @@
</form> </form>
</td> </td>
<td headers="t10" class="<%= row %>RowEvenCol"> <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>
<td headers="t11" class="<%= row %>RowOddCol"><%= Utils.addEntities(title) %></td> <td headers="t11" class="<%= row %>RowOddCol"><%= Utils.addEntities(title) %></td>
<td headers="t12" class="<%= row %>RowEvenCol"><%= workspaceItems[i].getCollection().getMetadata("name") %></td> <td headers="t12" class="<%= row %>RowEvenCol"><%= workspaceItems[i].getCollection().getMetadata("name") %></td>
@@ -332,7 +331,7 @@
</form> </form>
</td> </td>
<td class="<%= row %>RowEvenCol"> <td class="<%= row %>RowEvenCol">
<a href="mailto:<%= submitter.getEmail() %>"><%= submitter.getFullName() %></a> <a href="mailto:<%= submitter.getEmail() %>"><%= Utils.addEntities(submitter.getFullName()) %></a>
</td> </td>
<td class="<%= row %>RowOddCol"><%= Utils.addEntities(title) %></td> <td class="<%= row %>RowOddCol"><%= Utils.addEntities(title) %></td>
<td class="<%= row %>RowEvenCol"><%= supervisedItems[i].getCollection().getMetadata("name") %></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.app.webui.servlet.RegisterServlet" %>
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="org.dspace.core.Utils" %>
<% <%
EPerson eperson = (EPerson) request.getAttribute("eperson"); EPerson eperson = (EPerson) request.getAttribute("eperson");
@@ -43,9 +44,9 @@
<%-- <h1>Enter a New Password</h1> --%> <%-- <h1>Enter a New Password</h1> --%>
<h1><fmt:message key="jsp.register.new-password.title"/></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"> <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> </fmt:message></p>
<% <%

View File

@@ -25,6 +25,7 @@
<%@ page import="org.dspace.app.webui.servlet.RegisterServlet" %> <%@ page import="org.dspace.app.webui.servlet.RegisterServlet" %>
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="org.dspace.core.Utils" %>
<% <%
EPerson eperson = (EPerson) request.getAttribute("eperson"); EPerson eperson = (EPerson) request.getAttribute("eperson");
@@ -35,9 +36,9 @@
<%-- <h1>Registration Complete</h1> --%> <%-- <h1>Registration Complete</h1> --%>
<h1><fmt:message key="jsp.register.registered.title"/></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"> <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> </fmt:message></p>
<%-- <p>You're now registered to use the DSpace system. You can subscribe to <%-- <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.ChoiceAuthorityManager" %>
<%@ page import="org.dspace.content.authority.Choices" %> <%@ page import="org.dspace.content.authority.Choices" %>
<%@ page import="org.dspace.core.ConfigurationManager" %> <%@ 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://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
@@ -325,9 +326,9 @@
if (repeatable && !readonly && i < defaults.length) if (repeatable && !readonly && i < defaults.length)
{ {
name.setLength(0); name.setLength(0);
name.append(dpn.getLastName()) name.append(Utils.addEntities(dpn.getLastName()))
.append(' ') .append(' ')
.append(dpn.getFirstNames()); .append(Utils.addEntities(dpn.getFirstNames()));
// put a remove button next to filled in values // put a remove button next to filled in values
sb.append("<td><input type=\"submit\" name=\"submit_") sb.append("<td><input type=\"submit\" name=\"submit_")
.append(fieldName) .append(fieldName)

View File

@@ -281,7 +281,7 @@ function clearEPeople()
{ {
EPerson e = epeople[i]; EPerson e = epeople[i];
// Make sure no quotes in full name will mess up our Javascript // 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> <tr>
<td headers="t1" class="<%= row %>RowOddCol"> <td headers="t1" class="<%= row %>RowOddCol">
@@ -291,10 +291,10 @@ function clearEPeople()
<td headers="t2" class="<%= row %>RowEvenCol"><%= e.getID() %></td> <td headers="t2" class="<%= row %>RowEvenCol"><%= e.getID() %></td>
<td headers="t3" class="<%= row %>RowOddCol"><%= e.getEmail() %></td> <td headers="t3" class="<%= row %>RowOddCol"><%= e.getEmail() %></td>
<td headers="t4" class="<%= row %>RowEvenCol"> <td headers="t4" class="<%= row %>RowEvenCol">
<%= (e.getLastName() == null ? "" : e.getLastName()) %> <%= (e.getLastName() == null ? "" : Utils.addEntities(e.getLastName())) %>
</td> </td>
<td headers="t5" class="<%= row %>RowOddCol"> <td headers="t5" class="<%= row %>RowOddCol">
<%= (e.getFirstName() == null ? "" : e.getFirstName()) %> <%= (e.getFirstName() == null ? "" : Utils.addEntities(e.getFirstName())) %>
</td> </td>
<td headers="t6" class="<%= row %>RowOddCol"> <td headers="t6" class="<%= row %>RowOddCol">
<%= (e.getLanguage() == null ? "" : e.getLanguage()) %> <%= (e.getLanguage() == null ? "" : e.getLanguage()) %>

View File

@@ -26,6 +26,7 @@
<%@ page import="org.dspace.content.WorkspaceItem" %> <%@ page import="org.dspace.content.WorkspaceItem" %>
<%@ page import="org.dspace.eperson.EPerson" %> <%@ page import="org.dspace.eperson.EPerson" %>
<%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %> <%@ page import="javax.servlet.jsp.jstl.fmt.LocaleSupport" %>
<%@ page import="org.dspace.core.Utils" %>
<% <%
// get the workspace item from the request // 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"/> <p><fmt:message key="jsp.workspace.ws-main.submitmsg"/>
<%= workspaceItem.getCollection().getMetadata("name") %></p> <%= workspaceItem.getCollection().getMetadata("name") %></p>

View File

@@ -14,19 +14,14 @@
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-parent</artifactId> <artifactId>dspace-parent</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<!-- <properties>
The Subversion repository location is used by Continuum to update against <!-- This is the path to the root [dspace-src] directory. -->
when changes have occured, this spawns a new build cycle and releases snapshots <root.basedir>${basedir}/..</root.basedir>
into the snapshot repository below. </properties>
-->
<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>
<modules> <modules>
<module>dspace-jspui-api</module> <module>dspace-jspui-api</module>

View File

@@ -12,14 +12,14 @@
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-lni</artifactId> <artifactId>dspace-lni</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<scm> <properties>
<connection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-client</connection> <!-- This is the path to the root [dspace-src] directory. -->
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-client</developerConnection> <root.basedir>${basedir}/../..</root.basedir>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-client</url> </properties>
</scm>
<profiles> <profiles>
<profile> <profile>
@@ -82,6 +82,16 @@
</execution> </execution>
</executions> </executions>
</plugin> </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. This is another approach to packaging the LNI client that may be approached.
@@ -183,4 +193,4 @@
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -10,14 +10,14 @@
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-lni</artifactId> <artifactId>dspace-lni</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<scm> <properties>
<connection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-core</connection> <!-- This is the path to the root [dspace-src] directory. -->
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-core</developerConnection> <root.basedir>${basedir}/../..</root.basedir>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-core</url> </properties>
</scm>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -64,4 +64,4 @@
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -12,14 +12,14 @@
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-lni</artifactId> <artifactId>dspace-lni</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<scm> <properties>
<connection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-webapp</connection> <!-- This is the path to the root [dspace-src] directory. -->
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-webapp</developerConnection> <root.basedir>${basedir}/../..</root.basedir>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-lni/dspace-lni-webapp</url> </properties>
</scm>
<build> <build>
<plugins> <plugins>
@@ -46,6 +46,16 @@
<phase>prepare-package</phase> <phase>prepare-package</phase>
</execution> </execution>
</executions> </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> </plugin>
</plugins> </plugins>
</build> </build>
@@ -109,4 +119,4 @@
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -12,19 +12,14 @@
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-parent</artifactId> <artifactId>dspace-parent</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<!-- <properties>
The Subversion repository location is used by Continuum to update against <!-- This is the path to the root [dspace-src] directory. -->
when changes have occured, this spawns a new build cycle and releases snapshots <root.basedir>${basedir}/..</root.basedir>
into the snapshot repository below. </properties>
-->
<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>
<modules> <modules>
<module>dspace-lni-core</module> <module>dspace-lni-core</module>

View File

@@ -14,19 +14,14 @@
<parent> <parent>
<groupId>org.dspace</groupId> <groupId>org.dspace</groupId>
<artifactId>dspace-oai</artifactId> <artifactId>dspace-oai</artifactId>
<version>1.7.1-SNAPSHOT</version> <version>1.7.3</version>
<relativePath>..</relativePath>
</parent> </parent>
<!-- <properties>
The Subversion repository location is used by Continuum to update against <!-- This is the path to the root [dspace-src] directory. -->
when changes have occured, this spawns a new build cycle and releases snapshots <root.basedir>${basedir}/../..</root.basedir>
into the snapshot repository below. </properties>
-->
<scm>
<connection>scm:svn:http://scm.dspace.org/svn/repo/dspace/trunk/dspace-oai/dspace-oai-api</connection>
<developerConnection>scm:svn:https://scm.dspace.org/svn/repo/dspace/trunk/dspace-oai/dspace-oai-api</developerConnection>
<url>http://scm.dspace.org/svn/repo/dspace/trunk/dspace-oai/dspace-oai-api</url>
</scm>
<dependencies> <dependencies>
<dependency> <dependency>
@@ -48,4 +43,4 @@
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

Some files were not shown because too many files have changed in this diff Show More