Project

General

Profile

« Previous | Next » 

Revision 9119

Added by Jing Tao over 9 years ago

Add the code to get the head version.

View differences:

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