Revision 9119
Added by Jing Tao almost 10 years ago
src/edu/ucsb/nceas/metacat/IdentifierManager.java | ||
---|---|---|
58 | 58 |
import edu.ucsb.nceas.metacat.database.DBConnection; |
59 | 59 |
import edu.ucsb.nceas.metacat.database.DBConnectionPool; |
60 | 60 |
import edu.ucsb.nceas.metacat.database.DatabaseService; |
61 |
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService; |
|
61 | 62 |
import edu.ucsb.nceas.metacat.properties.PropertyService; |
62 | 63 |
import edu.ucsb.nceas.metacat.shared.AccessException; |
63 | 64 |
import edu.ucsb.nceas.metacat.shared.ServiceException; |
... | ... | |
931 | 932 |
|
932 | 933 |
/** |
933 | 934 |
* Get the pid of the head (current) version of objects match the specified sid. |
934 |
* DataONE defines the latest version as "current" if the object in question has |
|
935 |
* a matching SID and no value in the "obsoletedBy" field, regardless if it is "archived" or not. |
|
936 |
* If we can't find any pid associated with the sid doesn't have a value in obsoletedBy field, |
|
937 |
* the pid associated with the sid which has the max date_uploaded will be returned |
|
935 |
* 1. locate all candidate chain-ends for S1: |
|
936 |
* determined by: seriesId == S1 AND (obsoletedBy == null OR obsoletedBy.seriesId != S1) // these are the type1 and type2 ends |
|
937 |
* If obsoletedBy is missing, we generally consider it a type 2 end except: |
|
938 |
* there is another object in the chain (has the same series id) that obsoletes the missing object. |
|
939 |
* 2. if only 1 candidate chain-end, return it as the HEAD |
|
940 |
* 3. otherwise return the one in the chain with the latest dateUploaded value. |
|
938 | 941 |
* @param sid specified sid which should match. |
939 | 942 |
* @return the pid of the head version. The null will be returned if there is no pid found. |
940 | 943 |
* @throws SQLException |
... | ... | |
943 | 946 |
Identifier pid = null; |
944 | 947 |
if(sid != null && sid.getValue() != null && !sid.getValue().trim().equals("")) { |
945 | 948 |
logMetacat.debug("getting pid of the head version for matching the sid: " + sid.getValue()); |
946 |
String sql = "select guid from systemMetadata where obsoleted_by is null and series_id = ?";
|
|
949 |
String sql = "select guid from systemMetadata where series_id = ? order by date_uploaded DESC";
|
|
947 | 950 |
DBConnection dbConn = null; |
948 | 951 |
int serialNumber = -1; |
952 |
int endsCount = 0; |
|
953 |
boolean hasError = false; |
|
949 | 954 |
try { |
950 | 955 |
// Get a database connection from the pool |
951 | 956 |
dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getHeadPID"); |
... | ... | |
954 | 959 |
PreparedStatement stmt = dbConn.prepareStatement(sql); |
955 | 960 |
stmt.setString(1, sid.getValue()); |
956 | 961 |
ResultSet rs = stmt.executeQuery(); |
957 |
if (rs.next()) |
|
962 |
boolean hasNext = rs.next(); |
|
963 |
boolean first = true; |
|
964 |
Identifier firstOne = new Identifier();//since the sql using the desc order, the first one has the latest upload date. |
|
965 |
if (hasNext) |
|
958 | 966 |
{ |
959 |
pid = new Identifier(); |
|
960 |
pid.setValue(rs.getString(1)); |
|
961 |
|
|
967 |
while(hasNext) { |
|
968 |
String guidStr = rs.getString(1); |
|
969 |
Identifier guid = new Identifier(); |
|
970 |
guid.setValue(guidStr); |
|
971 |
if(first) { |
|
972 |
firstOne = guid; |
|
973 |
first =false; |
|
974 |
} |
|
975 |
SystemMetadata sysmeta = HazelcastService.getInstance().getSystemMetadataMap().get(guid); |
|
976 |
if(sysmeta.getObsoletedBy() == null) { |
|
977 |
//type 1 end |
|
978 |
System.out.println("has a type 1 end for sid "+sid.getValue()); |
|
979 |
pid = guid; |
|
980 |
endsCount++; |
|
981 |
} else { |
|
982 |
Identifier obsoletedBy = sysmeta.getObsoletedBy(); |
|
983 |
SystemMetadata obsoletedBySysmeta = HazelcastService.getInstance().getSystemMetadataMap().get(obsoletedBy); |
|
984 |
if(obsoletedBySysmeta != null) { |
|
985 |
Identifier sidInObsoletedBy = obsoletedBySysmeta.getSeriesId(); |
|
986 |
if(sidInObsoletedBy == null|| !sidInObsoletedBy.equals(sid)) { |
|
987 |
// type 2 end |
|
988 |
System.out.println("has a type 2 end for sid "+sid.getValue()); |
|
989 |
pid = guid; |
|
990 |
endsCount++; |
|
991 |
} |
|
992 |
} else { |
|
993 |
//obsoletedBySysmeta doesn't exist; it means the object is missing |
|
994 |
//generally, we consider it we generally consider it a type 2 end except: |
|
995 |
//there is another object in the chain (has the same series id) that obsoletes the missing object. |
|
996 |
String sql2 = "select guid from systemMetadata where obsoletes = ? and series_id = ?"; |
|
997 |
PreparedStatement stmt2 = dbConn.prepareStatement(sql2); |
|
998 |
stmt2.setString(1, obsoletedBy.getValue()); |
|
999 |
stmt2.setString(2, sid.getValue()); |
|
1000 |
ResultSet result = stmt2.executeQuery(); |
|
1001 |
boolean next = result.next(); |
|
1002 |
int count = 0; |
|
1003 |
while(next) { |
|
1004 |
count++; |
|
1005 |
next = result.next(); |
|
1006 |
} |
|
1007 |
if(count == 0) { |
|
1008 |
//the exception (another object in the chain (has the same series id) that obsoletes the missing object) doesn't exist |
|
1009 |
// it is a type 2 end |
|
1010 |
System.out.println("has a type 2 end for sid "+sid.getValue()); |
|
1011 |
pid = guid; |
|
1012 |
endsCount++; |
|
1013 |
} else if (count ==1) { |
|
1014 |
// it is not end, do nothing; |
|
1015 |
} else { |
|
1016 |
// something is wrong - there are more than one objects obsolete the missing object! |
|
1017 |
hasError = true; |
|
1018 |
break; |
|
1019 |
} |
|
1020 |
} |
|
1021 |
} |
|
1022 |
hasNext = rs.next(); |
|
1023 |
} |
|
1024 |
if(endsCount == 1) { |
|
1025 |
//it has one end and it is an ideal chain. We already assign the guid to the pid. So do nothing. |
|
1026 |
System.out.println("It is an ideal for sid "+sid.getValue()); |
|
1027 |
} |
|
1028 |
if(hasError || endsCount >1) { |
|
1029 |
// it is not an ideal chain, use the one with latest upload date(the first one in the result set since we have the desc order) |
|
1030 |
System.out.println("It is NOT an ideal for sid "+sid.getValue()); |
|
1031 |
pid = firstOne; |
|
1032 |
} |
|
962 | 1033 |
} else { |
963 |
//we don't find any pid associated with the sid doesn't have value in obsoletedBy field. |
|
964 |
//The pid associated with the sid which has the max date_uploaded will be returned. |
|
965 |
sql = "select guid from systemMetadata where series_id = ? and date_uploaded=(select max(date_uploaded) from systemMetadata where series_id = ?)"; |
|
966 |
stmt = dbConn.prepareStatement(sql); |
|
967 |
stmt.setString(1, sid.getValue()); |
|
968 |
stmt.setString(2, sid.getValue()); |
|
969 |
rs = stmt.executeQuery(); |
|
970 |
if(rs.next()) { |
|
971 |
pid = new Identifier(); |
|
972 |
pid.setValue(rs.getString(1)); |
|
973 |
} |
|
1034 |
//it is not a sid or at least we don't have anything to match it. |
|
1035 |
//do nothing, so null will be returned |
|
974 | 1036 |
} |
975 | 1037 |
|
976 | 1038 |
} catch (SQLException e) { |
Also available in: Unified diff
Add the code to get the head version.