Project

General

Profile

« Previous | Next » 

Revision 940

Added by Jing Tao over 22 years ago

A public method named getZippedPackage() and other relative private methods were add to this class. The public method can give a zip output stream if a docid and other parameters were passed to it.

View differences:

src/edu/ucsb/nceas/metacat/DBQuery.java
31 31

  
32 32
package edu.ucsb.nceas.metacat;
33 33

  
34
import edu.ucsb.nceas.morpho.datapackage.*;
34 35
import java.io.*;
35 36
import java.util.Vector;
37
import java.util.zip.*;
36 38
import java.net.URL;
37 39
import java.net.MalformedURLException;
38 40
import java.sql.*;
......
42 44
import java.io.File;
43 45
import java.io.FileWriter;
44 46
import java.io.BufferedWriter;
47
import javax.servlet.ServletOutputStream;
45 48

  
46 49
/** 
47 50
 * A Class that searches a relational DB for elements and 
......
55 58
  static final int ALL = 1;
56 59
  static final int WRITE = 2;
57 60
  static final int READ = 4;
58

  
61
 
59 62
  private Connection  conn = null;
60 63
  private String  parserName = null;
61 64
  private MetaCatUtil util = new MetaCatUtil();
......
110 113
          String docid = null;
111 114
          result.append("<?xml version=\"1.0\"?>\n");
112 115
          result.append("<resultset>\n"); 
113
  // following line removed by Dan Higgins to avoid insertion of query XML inside returned XML doc
114
  //        result.append("  <query>" + xmlfile + "</query>\n"); 
116
  
115 117
          if (!showRuntime)
116 118
          {
117 119
            Enumeration doclist = nodelist.keys();
......
452 454
              document.append("<subjectdoctype>").append(subDT);
453 455
              document.append("</subjectdoctype>");
454 456
            }
455
            document.append("<relationship>").append(MetaCatUtil.normalize(rel));
457
            document.append("<relationship>").
458
                                          append(MetaCatUtil.normalize(rel));
456 459
            document.append("</relationship>");
457 460
            document.append("<object>").append(MetaCatUtil.normalize(obj));
458 461
            document.append("</object>");
......
784 787
    AccessControlList aclobj = new AccessControlList(conn);
785 788
    return aclobj.hasPermission("READ", user, groups, docid);
786 789
  }
790

  
791
  /**
792
    * Get all docIds list for a data packadge
793
    * @param dataPackageDocid, the string in docId field of xml_relation table
794
    */
795
  private Vector getCurrentDocidListForDataPackage(String dataPackageDocid)
796
  {
797
    Vector docIdList=new Vector();//return value
798
    PreparedStatement pStmt;
799
    ResultSet rs=null;
800
    String docIdInSubjectField=null;
801
    String docIdInObjectField=null;
802
    //the query stirng
803
    String query="SELECT subject, object from xml_relation where docId = ?";
804
    try
805
    {
806
      pStmt=conn.prepareStatement(query);
807
      //bind the value to query
808
      pStmt.setString(1, dataPackageDocid);
809

  
810
      //excute the query
811
      pStmt.execute();
812
      //get the result set
813
      rs=pStmt.getResultSet();
814
      //process the result
815
      while (rs.next())
816
      {
817
        //In order to get the whole docIds in a data packadge,
818
        //we need to put the docIds of subject and object field in xml_relation
819
        //into the return vector
820
        docIdInSubjectField=rs.getString(1);//the result docId in subject field
821
        docIdInObjectField=rs.getString(2);//the result docId in object field
822

  
823
        //don't put the duplicate docId into the vector
824
        if (!docIdList.contains(docIdInSubjectField))
825
        {
826
          docIdList.add(docIdInSubjectField);
827
        }
828

  
829
        //don't put the duplicate docId into the vector
830
        if (!docIdList.contains(docIdInObjectField))
831
        {
832
          docIdList.add(docIdInObjectField);
833
        }
834
      }//while
835
      //close the pStmt
836
      pStmt.close();
837
    }//try
838
    catch (SQLException e)
839
    {
840
      util.debugMessage("Error in getDocidListForDataPackage: "
841
                            +e.getMessage());
842
    }//catch
843
    return docIdList;
844
  }//getCurrentDocidListForDataPackadge()
845
  
846
  /**
847
   * Get all docIds list for a data packadge
848
   * @param dataPackageDocid, the string in docId field of xml_relation table
849
   */
850
  private Vector getOldVersionDocidListForDataPackage(String dataPackageDocid)
851
                                 throws SQLException, McdbException,Exception
852
  {
787 853
   
854
    Vector docIdList=new Vector();//return value
855
    Vector tripleList=null;
856
    String xml=null;
857
    Connection dbConn=null;
858
    
859
    if (conn == null || conn.isClosed())
860
    {
861
      dbConn = util.openDBConnection();
862
    }
863
    else
864
    {
865
      dbConn=conn;
866
    }
867
    //initial a documentImpl object 
868
    DocumentImpl packageDocument = new DocumentImpl(dbConn, dataPackageDocid);
869
    //transfer to documentImpl object to string
870
    xml=packageDocument.toString();
871
    
872
    //create a tripcollection object
873
    TripleCollection tripleForPackage = new 
874
                                     TripleCollection(new StringReader(xml));
875
    //get the vetor of triples 
876
    tripleList=tripleForPackage.getCollection();
877
    
878
    for (int i= 0; i<tripleList.size(); i++)
879
    {
880
      //put subject docid  into docIdlist without duplicate
881
      if (!docIdList.contains(((Triple)tripleList.elementAt(i)).getSubject()))
882
      {
883
        //put subject docid  into docIdlist
884
         docIdList.add(((Triple)tripleList.get(i)).getSubject());
885
      }
886
      //put object docid into docIdlist without duplicate
887
      if (!docIdList.contains(((Triple)tripleList.elementAt(i)).getObject()))
888
      {
889
         docIdList.add(((Triple)(tripleList.get(i))).getObject());
890
      }
891
    }//for
892
    
893
    return docIdList;
894
  }//getDocidListForPackageInXMLRevisions()  
895
  
896
  /**
897
   * Check if the docId is a data packadge id. If the id is a data packadage 
898
   *id, it should be store in the docId fields in xml_relation table.
899
   *So we can use a query to get the entries which the docId equals the given 
900
   *value. If the result is null. The docId is not a packadge id. Otherwise,
901
   * it is.
902
   * @param docId, the id need to be checked
903
   */
904
  private boolean isDataPackageId(String docId)
905
  {
906
    boolean result=false;
907
    PreparedStatement pStmt;
908
    ResultSet rs=null;
909
    String query="SELECT docId from xml_relation where docId = ?";
910
    try
911
    {
912
      pStmt=conn.prepareStatement(query);
913
      //bind the value to query
914
      pStmt.setString(1, docId);
915
      //execute the query
916
      pStmt.execute();
917
      rs=pStmt.getResultSet();
918
      //process the result
919
      if (rs.next()) //There are some records for the id in docId fields
920
      {
921
        result=true;//It is a data packadge id
922
      }
923
      pStmt.close();
924
    }//try
925
    catch (SQLException e)
926
    {
927
      util.debugMessage("Error in getDocidListForDataPackadge: "
928
                            +e.getMessage());
929
    }
930
    return result;
931
  }//isDataPackageId()
932
  
933
  /**
934
   *Get the current Rev for a docid in xml_documents table
935
   * @param docId, the id need to get version numb
936
   * If the return value is -5, means no value in rev field for this docid
937
   */
938
  private int getCurrentRevFromXMLDoumentsTable(String docId)
939
  {
940
    int rev=-5;
941
    PreparedStatement pStmt;
942
    ResultSet rs=null;
943
    String query="SELECT rev from xml_documents where docId = ?";
944
    try
945
    {
946
      pStmt=conn.prepareStatement(query);
947
      //bind the value to query
948
      pStmt.setString(1, docId);
949
      //execute the query
950
      pStmt.execute();
951
      rs=pStmt.getResultSet();
952
      //process the result
953
      if (rs.next()) //There are some records for rev
954
      {
955
        rev=rs.getInt(1);;//It is the version for given docid
956
      }
957
      else
958
      {
959
        rev=-5;
960
      }
961
      pStmt.close();
962
    }//try
963
    catch (SQLException e)
964
    {
965
      util.debugMessage("Error in getDocidListForDataPackadge: "
966
                            +e.getMessage());
967
    }
968
    return rev;
969
  }//getCurrentRevFromXMLDoumentsTable
970
 
971
 /**
972
   *put a doc into a zip output stream
973
   *@param docImpl, docmentImpl object which will be sent to zip output stream
974
   *@param zipOut, zip output stream which the docImpl will be put
975
   *@param packageZipEntry, the zip entry name for whole package
976
   */
977
  private void addDocToZipOutputStream(DocumentImpl docImpl, 
978
                                ZipOutputStream zipOut, String packageZipEntry)
979
               throws ClassNotFoundException, IOException, SQLException, 
980
                      McdbException, Exception
981
  {
982
    byte[] byteString = null;
983
    ZipEntry zEntry = null;
984

  
985
    byteString = docImpl.toString().getBytes();
986
    //use docId as the zip entry's name
987
    zEntry = new ZipEntry(packageZipEntry+"/metadata/"+docImpl.getDocID());
988
    zEntry.setSize(byteString.length);
989
    zipOut.putNextEntry(zEntry);
990
    zipOut.write(byteString, 0, byteString.length);
991
    zipOut.closeEntry();
992
  
993
  }//addDocToZipOutputStream()
994

  
995
  
996
  /**
997
   *transfer a docid vetor to a documentImpl vector. The documentImpl vetor 
998
   *inlcudes current and old version
999
   *@param docIdList, a vetor hold a docid list for a data package. In docid,
1000
   *there is not version number in it.
1001
   */  
1002
  
1003
  private Vector getCurrentAllDocumentImpl( Vector docIdList)
1004
                              throws McdbException,Exception
1005
  {
1006
    Connection dbConn=null;
1007
    Vector documentImplList=new Vector();
1008
    int rev=0; 
1009
    
1010
    if (conn == null || conn.isClosed())
1011
    {
1012
      dbConn = util.openDBConnection();
1013
    }
1014
    else
1015
    {
1016
      dbConn=conn;
1017
    }
1018
    //for every docid in vector
1019
    for (int i=0;i<docIdList.size();i++)
1020
    {
1021
      //get newest version for this docId
1022
      rev=getCurrentRevFromXMLDoumentsTable((String)docIdList.elementAt(i));
1023
      //get all versions including current and old ones for one docid
1024
      for (int j=1;j<=rev;j++)
1025
      { 
1026
        String docidPlusVersion=((String)docIdList.elementAt(i))
1027
                        +util.getOption("accNumSeparator")+j;
1028
        //create new documentImpl object
1029
        DocumentImpl documentImplObject = 
1030
                                    new DocumentImpl(dbConn,docidPlusVersion);
1031
        //add them to vector                            
1032
        documentImplList.add(documentImplObject);
1033
      }//for
1034
    }//for
1035
    return documentImplList;
1036
  }
1037
  
1038
  /**
1039
   *transfer a docid vetor to a documentImpl vector. The documentImpl vetor 
1040
   *inlcudes old version
1041
   *@param docIdList, a vetor hold a docid list for a data package. In docid,
1042
   *there is version number in it.
1043
   */    
1044
  private Vector getOldVersionAllDocumentImpl( Vector docIdList)
1045
                              throws McdbException,Exception
1046
  {
1047
    Connection dbConn=null;
1048
    Vector documentImplList=new Vector();
1049
    String siteCode=null;
1050
    String uniqueId=null;
1051
    int rev=0; 
1052
    
1053
    if (conn == null || conn.isClosed())
1054
    {
1055
      dbConn = util.openDBConnection();
1056
    }
1057
    else
1058
    {
1059
      dbConn=conn;
1060
    }
1061
    //for every docid in vector
1062
    for (int i=0;i<docIdList.size();i++)
1063
    {
1064
      
1065
      //create a documentIdentifier object
1066
      DocumentIdentifier identifier=
1067
                        new DocumentIdentifier((String)docIdList.elementAt(i));
1068
      
1069
      //get newest version for this docId
1070
      siteCode=identifier.getSiteCode();
1071
      uniqueId=identifier.getUniqueId();
1072
      rev=Integer.parseInt(identifier.getRev());
1073
       
1074
      //get all versions including current and old ones for one docid
1075
      for (int j=1;j<=rev;j++)
1076
      { 
1077
        String docidPlusVersion=siteCode+util.getOption("accNumSeparator")+
1078
                        uniqueId+util.getOption("accNumSeparator")+j;
1079
        //create new documentImpl object
1080
        DocumentImpl documentImplObject = 
1081
                                    new DocumentImpl(dbConn,docidPlusVersion);
1082
        //add them to vector                            
1083
        documentImplList.add(documentImplObject);
1084
      }//for
1085
    }//for
1086
    return documentImplList;
1087
  }
1088
  /**
1089
   *put a data file into a zip output stream
1090
   *@param docImpl, docmentImpl object which will be sent to zip output stream
1091
   *@param zipOut, the zip output stream which the docImpl will be put
1092
   *@param packageZipEntry, the zip entry name for whole package
1093
   */
1094
  private void addDataFileToZipOutputStream(DocumentImpl docImpl,
1095
                                ZipOutputStream zipOut, String packageZipEntry)
1096
               throws ClassNotFoundException, IOException, SQLException,
1097
                      McdbException, Exception
1098
  {
1099
    byte[] byteString = null;
1100
    ZipEntry zEntry = null;
1101
    // this is data file; add file to zip
1102
    String filePath = util.getOption("datafilepath");
1103
    if (!filePath.endsWith("/")) 
1104
    {
1105
      filePath += "/";
1106
    }
1107
    String fileName = filePath + docImpl.getDocID();
1108
    zEntry = new ZipEntry(packageZipEntry+"/data/"+docImpl.getDocID());
1109
    zipOut.putNextEntry(zEntry);
1110
    FileInputStream fin = null;
1111
    try
1112
    {
1113
      fin = new FileInputStream(fileName);
1114
      byte[] buf = new byte[4 * 1024]; // 4K buffer
1115
      int b = fin.read(buf);
1116
      while (b != -1)
1117
      {
1118
        zipOut.write(buf, 0, b);
1119
        b = fin.read(buf);
1120
      }//while
1121
      zipOut.closeEntry();
1122
    }//try
1123
    catch (IOException ioe)
1124
    {
1125
      util.debugMessage("There is an exception: "+ioe.getMessage());
1126
    }//catch
1127
  }//addDataFileToZipOutputStream()
1128

  
1129
  /**
1130
   *create a html summary for data package and put it into zip output stream
1131
   *@param docImplList, the documentImpl ojbects in data package
1132
   *@param zipOut, the zip output stream which the html should be put
1133
   *@param packageZipEntry, the zip entry name for whole package
1134
   */
1135
   private void addHtmlSummaryToZipOutputStream(Vector docImplList,
1136
                                ZipOutputStream zipOut, String packageZipEntry)
1137
                                           throws Exception
1138
  {
1139
    StringBuffer htmlDoc = new StringBuffer();
1140
    ZipEntry zEntry = null;
1141
    byte[] byteString=null;
1142
    InputStream source;
1143
    DBTransform xmlToHtml;
1144
    Connection dbConn;
1145

  
1146
    //get the connection to the database
1147
    if (conn == null || conn.isClosed())
1148
    {
1149
      dbConn = util.openDBConnection();
1150
    }
1151
    else
1152
    {
1153
      dbConn=conn;
1154
    }
1155

  
1156
    //create a DBTransform ojbect
1157
    xmlToHtml = new DBTransform(dbConn);
1158
    //head of html
1159
    htmlDoc.append("<html><head></head><body>");
1160
    for (int i=0; i<docImplList.size(); i++)
1161
    {
1162
      if ((((DocumentImpl)docImplList.elementAt(i)).getDoctype()).
1163
                                                         compareTo("BIN")!=0)
1164
      { //this is an xml file so we can transform it.
1165
        //transform each file individually then concatenate all of the
1166
        //transformations together.
1167

  
1168
        //for metadata xml title
1169
        htmlDoc.append("<h2>");
1170
        htmlDoc.append(((DocumentImpl)docImplList.elementAt(i)).getDocID());
1171
        //htmlDoc.append(".");
1172
        //htmlDoc.append(((DocumentImpl)docImplList.elementAt(i)).getRev());
1173
        htmlDoc.append("</h2>");
1174
        //do the actual transform
1175
        StringWriter docString = new StringWriter();
1176
        xmlToHtml.transformXMLDocument(
1177
                        ((DocumentImpl)docImplList.elementAt(i)).toString(),
1178
           "-//NCEAS//eml-generic//EN", "-//W3C//HTML//EN", "html", docString);
1179
        htmlDoc.append(docString.toString());
1180
        htmlDoc.append("<br><br><hr><br><br>");
1181
      }//if
1182
      else
1183
      { //this is a data file so we should link to it in the html
1184
        htmlDoc.append("<a href=\"");
1185
        String dataFileName = null;
1186
        String dataFileid =((DocumentImpl)docImplList.elementAt(i)).getDocID();
1187
        htmlDoc.append("./data/").append(dataFileid).append("\">");
1188
        htmlDoc.append("Data File: ");
1189
        htmlDoc.append(dataFileid).append("</a><br>");
1190
        htmlDoc.append("<br><hr><br>");
1191
      }//else
1192
    }//for
1193
    htmlDoc.append("</body></html>");
1194
    byteString = htmlDoc.toString().getBytes();
1195
    zEntry = new ZipEntry(packageZipEntry+"/metadata.html");
1196
    zEntry.setSize(byteString.length);
1197
    zipOut.putNextEntry(zEntry);
1198
    zipOut.write(byteString, 0, byteString.length);
1199
    zipOut.closeEntry();
1200
    dbConn.close();
1201
        
1202
  }//addHtmlSummaryToZipOutputStream
1203
  
1204
  /**
1205
   * put a data packadge into a zip output stream
1206
   * @param docId, which the user want to put into zip output stream
1207
   * @param out, a servletoutput stream which the zip output stream will be put 
1208
   * @param user, the username of the user
1209
   * @param groups, the group of the user
1210
   */
1211
  public ZipOutputStream getZippedPackage(String docIdString, 
1212
                    ServletOutputStream out, String user, String[] groups)
1213
                    throws ClassNotFoundException, IOException, SQLException, 
1214
                      McdbException, NumberFormatException, Exception
1215
  { 
1216
    ZipOutputStream zOut = null;
1217
    String elementDocid=null;
1218
    DocumentImpl docImpls=null;
1219
    Connection dbConn = null;
1220
    Vector docIdList=new Vector();
1221
    Vector documentImplList= new Vector(); 
1222
    String packageId=null;
1223
    String rootName="package";//the package zip entry name
1224
    
1225
    String docId=null;
1226
    int version=-5;
1227
    docId=MetaCatUtil.getDocIdFromString(docIdString);
1228
    version=MetaCatUtil.getVersionFromString(docIdString);
1229
 
1230
    //get the connection to the database
1231
    if (conn == null || conn.isClosed())
1232
    {
1233
      dbConn = util.openDBConnection();
1234
    }
1235
    else
1236
    {
1237
      dbConn=conn;
1238
    }
1239

  
1240
    //check if the reqused docId is a data package id
1241
    if (!isDataPackageId(docId))//if it is not, throw a exception
1242
    {
1243
      Exception e = new Exception("The request the doc id " +docId+
1244
                                    " is not a data package id");
1245
      dbConn.close();
1246
      throw e;
1247
    }
1248
    else //it is a packadge id
1249
    { 
1250
      //store the package id
1251
      packageId=docId;
1252
      //If it is for current version
1253
      if ((version ==-1)||version==getCurrentRevFromXMLDoumentsTable(packageId))
1254
      { 
1255
        //get current version number
1256
        version=getCurrentRevFromXMLDoumentsTable(packageId);
1257
        //get package zip entry name
1258
        //it should be docId.revsion.package
1259
        rootName=packageId+util.getOption("accNumSeparator")+version+
1260
                                  util.getOption("accNumSeparator")+"package";
1261
        //get the whole id list for data packadge
1262
        docIdList=getCurrentDocidListForDataPackage(packageId);
1263
        //get the whole documentImple object
1264
        documentImplList=getCurrentAllDocumentImpl(docIdList);
1265
       
1266
      }//if
1267
      else  //for an old version
1268
      {
1269
       
1270
        rootName=docIdString+util.getOption("accNumSeparator")+"package";
1271
        //get the whole id list for data packadge
1272
        docIdList=getOldVersionDocidListForDataPackage(docIdString);
1273

  
1274
        //get the whole documentImple object
1275
        documentImplList=getOldVersionAllDocumentImpl(docIdList);
1276
      }//else  
1277
      
1278
      
1279
      zOut = new ZipOutputStream(out);
1280

  
1281
      //put every element into zip output stream
1282
      for (int i=0; i < documentImplList.size(); i++ )
1283
      {
1284
        //create a docmentImpls object (represent xml doc) base on the docId
1285
        docImpls=(DocumentImpl)documentImplList.elementAt(i);
1286

  
1287
         
1288
        if ((docImpls.getDoctype()).compareTo("BIN")!=0)
1289
        {
1290
          //if the docImpls is metadata
1291
          //add metadata into zip output stream
1292
          addDocToZipOutputStream(docImpls, zOut, rootName);
1293
        }
1294
        else //if the docImpls is a data file
1295
        {
1296
           //add data file into zip output stream too
1297
           addDataFileToZipOutputStream(docImpls, zOut, rootName);
1298
        }
1299

  
1300
      }//for
1301

  
1302
      //add html summary file
1303
      addHtmlSummaryToZipOutputStream(documentImplList, zOut, rootName);
1304
      zOut.finish(); //terminate the zip file
1305
      dbConn.close();
1306
      return zOut;
1307
    }//else
1308
  }//getZippedPackage()
1309
   
788 1310
}

Also available in: Unified diff