1   package eu.fbk.knowledgestore.populator.naf;
2   
3   import java.io.File;
4   import java.io.IOException;
5   import java.io.Writer;
6   import java.util.Hashtable;
7   import java.util.Iterator;
8   import java.util.LinkedList;
9   import java.util.List;
10  import java.util.Map;
11  import org.openrdf.model.URI;
12  import org.openrdf.model.impl.URIImpl;
13  import org.slf4j.Logger;
14  import org.slf4j.LoggerFactory;
15  
16  import eu.fbk.knowledgestore.OperationException;
17  import eu.fbk.knowledgestore.Session;
18  import eu.fbk.knowledgestore.data.ParseException;
19  import eu.fbk.knowledgestore.data.Record;
20  import eu.fbk.knowledgestore.data.Representation;
21  import eu.fbk.knowledgestore.vocabulary.KS;
22  
23  public class submitKS {
24      private static Logger logger = LoggerFactory.getLogger(submitKS.class);
25  
26      public static Integer init(Hashtable<String, KSPresentation> batchList, boolean store_partical_info, Session session) throws IOException{
27  	    
28  	List<Record> resources=null;
29  	List<Record> mentions=null;
30  	try {
31  		checkResourceFoundInKS(session,batchList);
32  	    // Clear all resources stored in the KS
33  	    // session.delete(KS.RESOURCE).exec();
34  
35  	    // Store resource records, in a single operation
36  	    resources = submitResources(batchList, session);
37  	    //store mentions records, in a single operation
38  	    mentions = submitMentions(batchList, session);
39          //upload news file
40          uploadNews(batchList, session);
41          // upload naf file
42          uploadNaf(batchList, session);
43  
44          LinkedList<KSPresentation> submittedFiles = getAllSubmittedFiles(batchList);
45          for (KSPresentation ksF : submittedFiles) {
46              if (nafPopulator.out != null) {
47                      nafPopulator.out.append("NAF: " + ksF.getNaf_file_path())
48                              .append(ksF.getStats().getStats()).append("\n");
49                      nafPopulator.out.flush();
50              }
51              nafPopulator.updatestats(ksF.getStats());
52          }
53      
54  	    return 1;
55  	} catch (ParseException e) {
56  	    //e.printStackTrace();
57  	    //rollback
58          logger.error(e.getMessage(), e);
59  	    rollback(session,resources,mentions);
60  	    //inout.append(e.getMessage());
61  	    return 0;
62  	} catch (IllegalStateException e) {
63  	    //rollback
64          logger.error(e.getMessage(), e);
65  	    rollback(session,resources,mentions);
66  	    return 0;
67  	} catch (OperationException e) {
68  	    //rollback
69  	    logger.error(e.getMessage(), e);
70  	    rollback(session,resources,mentions);
71              
72  	    return 0;
73  	} catch (IOException e) {
74  	    //rollback
75          logger.error(e.getMessage(), e);
76  	    rollback(session,resources,mentions);
77  	    return 0;
78  	}
79  		
80      }
81      
82      private static boolean doSubmitToKS(KSPresentation tmp){
83          //Default 1=discard the new, 2=ignore repopulate, 3=delete repopulate
84      	if(nafPopulator.KSresourceReplacement==1&&!tmp.isFoundInKS())
85      		return true;
86      	if(nafPopulator.KSresourceReplacement==2)
87      		return true;
88      	if(nafPopulator.KSresourceReplacement==3){
89      		if(tmp.isFoundInKS()){
90      			//TODO do the deletion of the previous ks resources then return true;
91      		}
92      		return true;
93      	}
94      		
95      	return false;
96      }
97  	
98      private static void checkResourceFoundInKS(
99  			Session session, Hashtable<String, KSPresentation> batchList) {
100     	if(nafPopulator.KSresourceReplacement!=2){
101     	for (KSPresentation tmp : batchList.values()) {
102     	    try {
103                 Record record = session.retrieve(KS.RESOURCE).ids(tmp.getNaf().getID())
104                         .properties(KS.STORED_AS).exec().getUnique();
105                 boolean correctlyPopulated = record != null && !record.isNull(KS.STORED_AS);
106 //    			long cc = session.count(KS.RESOURCE).ids(tmp.getNewsResource().getID()).exec();//TODO
107     			if(correctlyPopulated)
108     				tmp.setFoundInKS(true);
109     			else
110     				tmp.setFoundInKS(false);
111     			
112     		} catch (IllegalStateException e) {
113     			tmp.setFoundInKS(false);
114     		    logger.error(e.getMessage(), e);
115     		} catch (OperationException e) {
116     			tmp.setFoundInKS(false);
117     		    logger.error(e.getMessage(), e);
118     		}
119     	  }
120     	}
121 	}
122 
123 	private static void rollback(Session session, List<Record> resources, List<Record> mentions){
124 	List<URI> idsIT;
125 	
126 	try {
127 	    // delete the resources by id
128 	    idsIT = new LinkedList<URI>();
129 	    for(Record rID : resources){
130 		idsIT.add(rID.getID());
131 	    }
132 	    session.delete(KS.RESOURCE).ids(idsIT).exec();
133 
134 	    // delete the mentions by id
135 	    idsIT.clear();
136 	    for(Record rID : mentions){
137 		idsIT.add(rID.getID());
138 	    }
139 	    session.delete(KS.MENTION).ids(idsIT).exec();
140 
141         } catch (ParseException e) {
142             logger.error("Error rollback: "+e.getMessage());
143         } catch (IllegalStateException e) {
144             logger.error("Error rollback: "+e.getMessage());
145         } catch (OperationException e) {
146             logger.error("Error rollback: "+e.getMessage());
147         }
148     }
149 
150     private static List<Record> submitMentions(Hashtable<String, KSPresentation> batchList, Session session) throws ParseException, IllegalStateException, OperationException {
151 	final List<Record> records = getAllMentionType(batchList);
152 	if(records.size()>0)
153 	session.merge(KS.MENTION).criteria("overwrite *").records(records)
154 	    .exec();
155 	// Count and print the number of resources in the KS
156 	// final long numResources = session.count(KS.MENTION).exec();
157 	// System.out.println(numResources + " mentions in the KS");
158 	
159 	// return the list of submitted mentions
160 	return records;
161     }
162 
163     private static List<Record> submitResources(Hashtable<String, KSPresentation> batchList, Session session) throws IllegalStateException, OperationException, IOException {
164 	final List<Record> records = getAllResourceType(batchList);
165 	if(records.size()>0)
166 	session.merge(KS.RESOURCE).criteria("overwrite *").records(records)
167 	    .exec();
168 	// Count and print the number of resources in the KS
169 	// final long numResources = session.count(KS.RESOURCE).exec();
170 	// System.out.println(numResources + " resources in the KS");
171 	return records;
172     }
173 
174     private static Hashtable<URI, String> uploadNaf(Hashtable<String, KSPresentation> batchList, Session session) throws IllegalStateException, OperationException {
175 	Hashtable<URI, String> FILE_RESOURCES = getAllNafResources(batchList);
176 	// Store resource files, one at a time
177 	for (final Map.Entry<URI, String> entry : FILE_RESOURCES.entrySet()) {
178 	    final URI resourceID = entry.getKey();
179 	    final File nafFile = new File(entry.getValue());
180 	    final Representation representation = Representation.create(nafFile, true);
181 	    try {
182 		session.upload(resourceID).representation(representation).exec();
183 	    } finally {
184 		representation.close();
185 
186 		// delete the nafFile if it is a temporary file extracted from a zip or tgz archive
187 		if (nafPopulator.ZInFile || nafPopulator.TInFile) {
188 		    nafFile.delete();
189 		}
190 	    }
191 	}
192 	return FILE_RESOURCES;
193     }
194 
195     private static Hashtable<URI, String> uploadNews(Hashtable<String, KSPresentation> batchList, Session session) throws IllegalStateException, OperationException {
196 	Hashtable<URI, String> FILE_RESOURCES = getAllResources(batchList);
197 	// Store resource files, one at a time
198 	for (final Map.Entry<URI, String> entry : FILE_RESOURCES.entrySet()) {
199 	    final URI resourceID = entry.getKey();
200 	    final Representation representation = Representation.create(entry
201 									.getValue());
202 	    try {
203 		session.upload(resourceID).representation(representation)
204 		    .exec();
205 	    } finally {
206 		representation.close();
207 	    }
208 	}
209 	return FILE_RESOURCES;
210     }
211 
212     private static List<Record> getAllResourceType(Hashtable<String, KSPresentation> batchList) throws IOException {
213 	List<Record> temp = new LinkedList<Record>();
214 	for (KSPresentation tmp : batchList.values()) {
215 		if(doSubmitToKS(tmp)){
216 	    temp.add(tmp.getNewsResource());
217 	    temp.add(tmp.getNaf());
218 	    /*inout.append(tmp.getNewsResource().toString(Data.getNamespaceMap(),
219 	      true)
220 	      + "\n");
221 	      inout.append(tmp.getNaf().toString(Data.getNamespaceMap(), true)
222 	      + "\n");*/
223 		}
224 	}
225 	return temp;
226     }
227 
228     private static Hashtable<URI, String> getAllNafResources(Hashtable<String, KSPresentation> batchList) {
229 	Hashtable<URI, String> temp = new Hashtable<URI, String>();
230 	for (KSPresentation tmp : batchList.values()) {
231 		if(doSubmitToKS(tmp)){
232 	    temp.put(tmp.getNaf().getID(), tmp.getNaf_file_path());
233 		}
234 	}
235 	return temp;
236     }
237 
238     private static Hashtable<URI, String> getAllResources(Hashtable<String, KSPresentation> batchList) {
239 	Hashtable<URI, String> temp = new Hashtable<URI, String>();
240 	for (KSPresentation tmp : batchList.values()) {
241 		if(doSubmitToKS(tmp)){
242 	    temp.put(tmp.getNewsResource().getID(), tmp.getNews());
243 		}
244 	}
245 	return temp;
246     }
247 
248     private static List<Record> getAllMentionType(Hashtable<String, KSPresentation> batchList) {
249 	List<Record> temp = new LinkedList<Record>();
250 	for (KSPresentation tmp : batchList.values()) {
251 		if(doSubmitToKS(tmp)){
252 	    temp.addAll(tmp.getMentions().values());
253 		}
254 	}
255 	return temp;
256     }
257     private static LinkedList<KSPresentation> getAllSubmittedFiles(Hashtable<String, KSPresentation> batchList) {
258     	LinkedList<KSPresentation> temp = new LinkedList<KSPresentation>();
259     	for (KSPresentation tmp : batchList.values()) {
260     		if(doSubmitToKS(tmp)){
261     	    temp.addLast(tmp);
262     		}else{
263     			logger.error("submitKS: NAF: "+tmp.getNaf_file_path()+" - File already exists in KS, discarded!");
264     		}
265     	}
266     	return temp;
267         }
268 }