Skip to content

Commit cfc9abe

Browse files
authored
Merge pull request #8 from sem42198/working_branch
Working branch
2 parents 24a7f6f + bd490ac commit cfc9abe

File tree

7 files changed

+442
-337
lines changed

7 files changed

+442
-337
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,12 @@ We recommend migrating to the latest version of ArchivesSpace when possible. Arc
1616
5. Change the default information in the migration tool user interface as needed.
1717
6. Press the "Copy To Archives Space" button to start the migration process.
1818
7. Assess the migration using the migration report and clean up data as needed.
19+
20+
####Notes For Developers
21+
22+
To build this tool, use the IDE of your choice to build a standalone jar executable. Most of development work will probably take place on the following classes.
23+
24+
* ASpaceCopyUtil - This class essentially controls the migration process and interacts with the UI (dbCopyFrame) as well as the classes listed below.
25+
* ASpaceMapper - Converts Archon JSON records to the ArchivesSpace JSON model.
26+
* ASpaceClient - Saves records to ASpace through http post.
27+
* ASpaceEnumUtil - Converts an Archon enum ID to the corresponding ASpace enum. Usually called by ASpaceMapper.
396 KB
Binary file not shown.
256 KB
Binary file not shown.

src/org/nyu/edu/dlts/dbCopyFrame.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ private void initComponents() {
610610
}));
611611

612612
//---- apiLabel ----
613-
apiLabel.setText(" Archives Space Version: v1.4.x");
613+
apiLabel.setText(" Archives Space Version: v2.x");
614614
apiLabel.setHorizontalTextPosition(SwingConstants.CENTER);
615615
contentPanel.add(apiLabel, cc.xy(1, 1));
616616

src/org/nyu/edu/dlts/utils/ASpaceCopyUtil.java

Lines changed: 317 additions & 203 deletions
Large diffs are not rendered by default.

src/org/nyu/edu/dlts/utils/ASpaceEnumUtil.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ public String getASpaceNameSource(int arID) {
199199
return getEnumValueForID(key, "local");
200200
}
201201

202+
public String getASpaceNameSourceForSubject(int arID) {
203+
String key = "name_subject_source_" + arID;
204+
return getEnumValueForID(key, "local");
205+
}
206+
202207
/**
203208
* Method to initASpaceialize the name rules array
204209
*/
@@ -1235,8 +1240,9 @@ public void setASpaceDynamicEnums(HashMap<String, JSONObject> dynamicEnums) {
12351240
* @param listName
12361241
* @return
12371242
*/
1238-
public JSONObject getDynamicEnum(String listName) throws Exception {
1243+
public ArrayList<JSONObject> getDynamicEnum(String listName) throws Exception {
12391244
JSONObject dynamicEnum = null;
1245+
JSONObject dynamicEnum2 = null;
12401246

12411247
if (listName.contains("countries")) {
12421248
dynamicEnum = dynamicEnums.get("country_iso_3166");
@@ -1275,9 +1281,17 @@ public JSONObject getDynamicEnum(String listName) throws Exception {
12751281
dynamicEnum = dynamicEnums.get("subject_source");
12761282
dynamicEnum.put("valueKey", "EADSource");
12771283
dynamicEnum.put("idPrefix", "subject_source");
1284+
// since some subjects get mapped to agents we need the Archon's subject sources for agents as well as subjects
1285+
dynamicEnum2 = dynamicEnums.get("name_source");
1286+
dynamicEnum2.put("valueKey", "EADSource");
1287+
dynamicEnum2.put("idPrefix", "name_subject_source");
12781288
}
12791289

1280-
return dynamicEnum;
1290+
ArrayList<JSONObject> dynamicEnums = new ArrayList<JSONObject>();
1291+
dynamicEnums.add(dynamicEnum);
1292+
dynamicEnums.add(dynamicEnum2);
1293+
1294+
return dynamicEnums;
12811295
}
12821296

12831297
/**

src/org/nyu/edu/dlts/utils/ASpaceMapper.java

Lines changed: 99 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ public class ASpaceMapper {
5454

5555
// date formatter used to convert date string to date object
5656
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
57-
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyyddMM");
58-
SimpleDateFormat humanDateFormat = new SimpleDateFormat("MM/dd/yyyy");
59-
6057

6158
// booleans used to convert some bbcode to html or blanks
6259
private boolean bbcodeToHTML = false;
@@ -128,68 +125,72 @@ public ASpaceEnumUtil getEnumUtil() {
128125
* @param enumList
129126
* @return
130127
*/
131-
public JSONObject mapEnumList(JSONObject enumList, String endpoint) throws Exception {
128+
public ArrayList<JSONObject> mapEnumList(JSONObject enumList, String endpoint) throws Exception {
132129
// first we get the correct dynamic enum based on list. If it null then we just return null
133-
JSONObject dynamicEnumJS = enumUtil.getDynamicEnum(endpoint);
134-
135-
if(dynamicEnumJS == null) return null;
130+
ArrayList<JSONObject> dynamicEnums = enumUtil.getDynamicEnum(endpoint);
131+
ArrayList<JSONObject> dynamicEnumsUpdated = new ArrayList<JSONObject>();
136132

137-
// add the values return from aspace enum an arraylist to make lookup easier
138-
JSONArray valuesJA = dynamicEnumJS.getJSONArray("values");
139-
ArrayList<String> valuesList = new ArrayList<String>();
140-
for(int i = 0; i < valuesJA.length(); i++) {
141-
valuesList.add(valuesJA.getString(i));
142-
}
133+
for (JSONObject dynamicEnumJS : dynamicEnums) {
143134

144-
// now see if all the archon values are in the ASpace list already
145-
// if they are not then add them
146-
String valueKey = dynamicEnumJS.getString("valueKey");
147-
String idPrefix = dynamicEnumJS.getString("idPrefix");
135+
if (dynamicEnumJS == null) return dynamicEnumsUpdated;
148136

149-
boolean toLowerCase = true;
150-
if(dynamicEnumJS.has("keepValueCase")) {
151-
toLowerCase = false;
152-
}
137+
// add the values return from aspace enum an arraylist to make lookup easier
138+
JSONArray valuesJA = dynamicEnumJS.getJSONArray("values");
139+
ArrayList<String> valuesList = new ArrayList<String>();
140+
for (int i = 0; i < valuesJA.length(); i++) {
141+
valuesList.add(valuesJA.getString(i));
142+
}
153143

154-
int count = 0;
155-
Iterator<String> keys = enumList.keys();
156-
while(keys.hasNext()) {
157-
JSONObject enumJS = enumList.getJSONObject(keys.next());
158-
String value = enumJS.getString(valueKey);
144+
// now see if all the archon values are in the ASpace list already
145+
// if they are not then add them
146+
String valueKey = dynamicEnumJS.getString("valueKey");
147+
String idPrefix = dynamicEnumJS.getString("idPrefix");
159148

160-
// most values in ASpace are lower case so normalize
161-
if(toLowerCase) {
162-
value = value.toLowerCase();
149+
boolean toLowerCase = true;
150+
if (dynamicEnumJS.has("keepValueCase")) {
151+
toLowerCase = false;
163152
}
164153

165-
// some values have spaces which space normally uses underscore for
166-
value = value.replace(" ", "_");
154+
int count = 0;
155+
Iterator<String> keys = enumList.keys();
156+
while (keys.hasNext()) {
157+
JSONObject enumJS = enumList.getJSONObject(keys.next());
158+
String value = enumJS.getString(valueKey);
159+
160+
// most values in ASpace are lower case so normalize
161+
if (toLowerCase) {
162+
value = value.toLowerCase();
163+
}
164+
165+
// some values have spaces which space normally uses underscore for
166+
value = value.replace(" ", "_");
167167

168-
// map the id to value
169-
String id = idPrefix + "_" + enumJS.get("ID");
170-
enumUtil.addIdAndValueToEnumList(id, value);
171-
if (idPrefix.equals("container_types")) {
172-
aspaceCopyUtil.addContainerTypeValueToIDMapping(value, enumJS.getString("ID"));
168+
// map the id to value
169+
String id = idPrefix + "_" + enumJS.get("ID");
170+
enumUtil.addIdAndValueToEnumList(id, value);
171+
if (idPrefix.equals("container_types")) {
172+
aspaceCopyUtil.addContainerTypeValueToIDMapping(value, enumJS.getString("ID"));
173+
}
174+
175+
// see if to add this to aspace
176+
if (!valuesList.contains(value)) {
177+
valuesJA.put(value);
178+
count++;
179+
System.out.println("Adding value " + value);
180+
}
173181
}
174182

175-
// see if to add this to aspace
176-
if(!valuesList.contains(value)) {
177-
valuesJA.put(value);
178-
count++;
179-
System.out.println("Adding value " + value);
183+
// need to add other to extent unit type enum list
184+
if (endpoint.contains("extentunits")) {
185+
valuesJA.put(ASpaceEnumUtil.UNMAPPED);
180186
}
181-
}
182187

183-
// need to add other to extent unit type enum list
184-
if(endpoint.contains("extentunits")) {
185-
valuesJA.put(ASpaceEnumUtil.UNMAPPED);
186-
}
187188

188-
if(count != 0) {
189-
return dynamicEnumJS;
190-
} else {
191-
return null;
189+
if (count != 0) {
190+
dynamicEnumsUpdated.add(dynamicEnumJS);
191+
}
192192
}
193+
return dynamicEnumsUpdated;
193194
}
194195

195196
/**
@@ -215,6 +216,7 @@ public String getCorporateAgent(JSONObject repository) throws JSONException {
215216
contactsJS.put("address_1", repository.get("Address"));
216217
contactsJS.put("address_2", repository.get("Address2"));
217218
contactsJS.put("city", repository.get("City"));
219+
contactsJS.put("region", repository.get("State"));
218220

219221
// add the country and country code together
220222
contactsJS.put("country", enumUtil.getASpaceCountryCode(repository.getInt("CountryID")));
@@ -292,6 +294,7 @@ public String convertRepository(JSONObject record, String agentURI) throws Excep
292294
json.put("org_code", record.get("Code"));
293295
json.put("url", fixUrl(record.getString("URL")));
294296
json.put("publish", true);
297+
json.put("country", enumUtil.getASpaceCountryCode(record.getInt("CountryID")));
295298

296299
if(agentURI != null) {
297300
json.put("agent_representation", getReferenceObject(agentURI));
@@ -422,7 +425,9 @@ public JSONObject convertCreator(JSONObject record, int creatorTypeId) throws Ex
422425
}
423426

424427
// add the source for the name
425-
namesJS.put("source", enumUtil.getASpaceNameSource(record.getInt("CreatorSourceID")));
428+
if (record.has("SubjectSourceID")) {
429+
namesJS.put("source", enumUtil.getASpaceNameSourceForSubject(record.getInt("SubjectSourceID")));
430+
} else namesJS.put("source", enumUtil.getASpaceNameSource(record.getInt("CreatorSourceID")));
426431

427432
// add basic information to the names record
428433
String sortName = record.getString("Name");
@@ -897,11 +902,12 @@ public HashMap<String, String> getFileIDsToFilenamesMap() {
897902
* Method to convert an collection record to json ASpace JSON
898903
*
899904
* @param record
900-
* @param classificationIdPartsMap
905+
* @param classificationIdentifiers
901906
* @return
902907
* @throws Exception
903908
*/
904-
public JSONObject convertCollection(JSONObject record, HashMap<String, String> classificationIdPartsMap) throws Exception {
909+
public JSONObject convertCollection(JSONObject record, HashMap<String, String> classificationIdentifiers,
910+
HashMap<String, String> classificationParents) throws Exception {
905911
// Main json object
906912
JSONObject json = new JSONObject();
907913

@@ -934,30 +940,35 @@ public JSONObject convertCollection(JSONObject record, HashMap<String, String> c
934940

935941
// get the ids and make them unique if we in DEBUG mode
936942
String id = record.getString("CollectionIdentifier");
943+
944+
// if the collection ID is empty fix it
945+
if (id == null || id.isEmpty()) {
946+
id = "##" + randomString.nextString();
947+
while (resourceIDs.contains(id)) {
948+
id = "##" + randomString.nextString();
949+
}
950+
aspaceCopyUtil.addErrorMessage("Empty collection ID. Changed to " + id + "\n");
951+
}
952+
937953
String classificationID = record.getString("ClassificationID");
938954
String[] idParts = new String[]{"", "", "", ""};
939955

940-
if(!classificationID.equals("0") && classificationIdPartsMap.get(classificationID) != null) {
941-
String[] sa = classificationIdPartsMap.get(classificationID).split("/");
942-
943-
// this can be placed in a loop but lets keep it nice an clear?
944-
if(sa.length == 1) {
945-
idParts[0] = sa[0];
946-
idParts[1] = id;
947-
} else if(sa.length == 2) {
948-
idParts[0] = sa[0];
949-
idParts[1] = sa[1];
950-
idParts[2] = id;
951-
} else if (sa.length == 3) {
952-
idParts[0] = sa[0];
953-
idParts[1] = sa[1];
954-
idParts[2] = sa[2];
955-
idParts[3] = id;
956-
}
957-
} else {
958-
idParts[0] = id;
956+
Stack<String> fullId = new Stack<String>();
957+
fullId.push(id);
958+
String cId = classificationID;
959+
while (cId != null) {
960+
String identifier = classificationIdentifiers.get(cId);
961+
if (identifier == null) break;
962+
fullId.push(identifier);
963+
cId = classificationParents.get(cId);
959964
}
960965

966+
idParts[0] = fullId.pop();
967+
if (!fullId.isEmpty()) idParts[1] = fullId.pop();
968+
if (!fullId.isEmpty()) idParts[2] = fullId.pop();
969+
while (fullId.size() > 1) idParts[2] += "-" + fullId.pop();
970+
if (!fullId.isEmpty()) idParts[3] = fullId.pop();
971+
961972
// make sure the id is unique
962973
getUniqueID(ASpaceClient.RESOURCE_ENDPOINT, "", idParts, title);
963974

@@ -1215,58 +1226,12 @@ public JSONObject convertCollectionContent(JSONObject record) throws Exception {
12151226
json.put("component_id", record.getString("UniqueID"));
12161227
}
12171228

1218-
//json.put("position", record.getInt("SortOrder"));
1219-
1220-
// place a dummy key to help with the sorting if we redoing the sorting
1221-
String paddedSortOrder = String.format("%05d", record.getInt("SortOrder"));
1222-
json.put("sort_key1", paddedSortOrder + "_" + record.get("ID"));
1223-
json.put("sort_key2", ""); // sort order of the parent physical only content record
1224-
12251229
// add the notes
12261230
addResourceComponentNotes(record, json);
12271231

12281232
return json;
12291233
}
12301234

1231-
/**
1232-
* Method to convert container information for physical only component
1233-
* into a component
1234-
*
1235-
* @param aoEndpoint
1236-
* @param containerList
1237-
* @return
1238-
* @throws Exception
1239-
*/
1240-
public JSONObject convertContainerInformation(String aoEndpoint, ArrayList<String> containerList) throws Exception {
1241-
String[] sa = containerList.get(0).split("::");
1242-
1243-
// Main json object
1244-
JSONObject json = new JSONObject();
1245-
1246-
json.put("uri", aoEndpoint + "/" + sa[2]);
1247-
json.put("jsonmodel_type", "archival_object");
1248-
1249-
json.put("publish", publishRecord);
1250-
1251-
1252-
/* Add fields needed for abstract_archival_object.rb */
1253-
1254-
// check to make sure we have a title
1255-
String title = WordUtils.capitalize(sa[0] + " " + sa[1]);
1256-
json.put("title", title);
1257-
1258-
/* add field required for archival_object.rb */
1259-
json.put("level", "item");
1260-
1261-
// make the ref id unique otherwise ASpace complains
1262-
String refId = sa[2];
1263-
json.put("ref_id", refId);
1264-
1265-
json.put("position", new Integer(sa[3]));
1266-
1267-
return json;
1268-
}
1269-
12701235
/**
12711236
* Method to add a date json object
12721237
*
@@ -1480,7 +1445,17 @@ private void addSinglePartNote(JSONArray notesJA, String noteType, String noteLa
14801445
* @throws Exception
14811446
*/
14821447
private void addMultipartNote(JSONArray notesJA, String noteType, String noteLabel, String noteContent) throws Exception {
1483-
if(noteContent.isEmpty() || noteType.isEmpty()) return;
1448+
if(noteContent.trim().isEmpty() || noteType.isEmpty()) return;
1449+
1450+
// these note types don't exist in ASpace
1451+
if (noteType.equals("unitid") || noteType.equals("origination") || noteType.equals("note")) noteType = "odd";
1452+
1453+
// these note types should be single part
1454+
if (noteType.equals("physfacet") || noteType.equals("physdesc") || noteType.equals("langmaterial") ||
1455+
noteType.equals("materialspec")) {
1456+
addSinglePartNote(notesJA, noteType, noteLabel, noteContent);
1457+
return;
1458+
}
14841459

14851460
JSONObject noteJS = new JSONObject();
14861461

@@ -1857,19 +1832,12 @@ private Date getDate(String dateString) {
18571832
* @return
18581833
*/
18591834
private String getHumanReadableDate(String dateString) {
1860-
Date date = null;
1861-
18621835
try {
1863-
date = simpleDateFormat.parse(dateString);
1864-
} catch (ParseException e) { }
1865-
1866-
try {
1867-
date = simpleDateFormat2.parse(dateString);
1868-
} catch (ParseException e) { }
1869-
1870-
if(date != null) {
1871-
return humanDateFormat.format(date);
1872-
} else {
1836+
String year = dateString.substring(0, 4);
1837+
String month = dateString.substring(4, 6);
1838+
String day = dateString.substring(6);
1839+
return month + "/" + day + "/" + year;
1840+
} catch (Exception e) {
18731841
return dateString;
18741842
}
18751843
}

0 commit comments

Comments
 (0)