/* * © Copyright IBM Corp. 2013 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package nsf.playground.impexp; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.text.ParseException; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Vector; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import lotus.domino.Database; import lotus.domino.Document; import lotus.domino.Item; import lotus.domino.NotesException; import lotus.domino.Session; import com.ibm.commons.util.StringUtil; import com.ibm.commons.util.io.json.JsonException; import com.ibm.commons.util.io.json.JsonGenerator; import com.ibm.commons.util.io.json.JsonJavaArray; import com.ibm.commons.util.io.json.JsonJavaFactory; import com.ibm.commons.util.io.json.JsonJavaObject; import com.ibm.commons.util.io.json.JsonParser; /** * Class for JSON import. * * @author priand */ public class JsonImport extends JsonImportExport { public static class Entry { private String unid; private JsonJavaObject object; public Entry(String unid, JsonJavaObject object) { this.unid = unid; this.object = object; } public String getUnid() { return unid; } public JsonJavaObject getJsonObject() { return object; } } public interface ImportSource { public void startImport() throws IOException; public void endImport() throws IOException; public Entry next() throws IOException; } public static class ZipImportSource implements ImportSource { private ZipInputStream zipIs; public ZipImportSource(InputStream is) throws IOException { this.zipIs = new ZipInputStream(is); } public void startImport() throws IOException { } public void endImport() throws IOException { } public Entry next() throws IOException { while(zipIs!=null) { ZipEntry e = zipIs.getNextEntry(); if(e==null) { zipIs = null; break; } String name = e.getName(); if(name.endsWith(JsonImportExport.DOCUMENT_EXTENSION)) { String unid = decodeFileName(name.substring(0,name.length()-JsonImportExport.DOCUMENT_EXTENSION.length())); int pos = unid.lastIndexOf('/'); if(pos>0) { unid = unid.substring(pos+1); } try { JsonJavaObject o = (JsonJavaObject)JsonParser.fromJson(JsonJavaFactory.instanceEx2, new InputStreamReader(zipIs,"UTF-8")); return new Entry(unid,o); } catch (JsonException ex) { throw new IOException(ex); } } } return null; } } private ImportSource source; public JsonImport(ImportSource source) { this.source = source; } public void importDocuments(Database database) throws IOException { source.startImport(); try { Session session = database.getParent(); for( Entry e=source.next(); e!=null; e=source.next() ) { Document doc = database.createDocument(); try { doc.setUniversalID(e.getUnid()); importDocument(session,doc,e.getJsonObject()); if(getDocumentFilter()==null || getDocumentFilter().accept(doc)) { doc.save(); } } finally { doc.recycle(); } } } catch(NotesException ex) { throw new IOException(ex); } finally { source.endImport(); } } protected void importDocument(Session session, Document doc, JsonJavaObject jsDoc) throws IOException, NotesException { Map<String,Object> allFlags = (Map<String,Object>)jsDoc.get(FLAGS_FIELD); for(Map.Entry<String, Object> e: jsDoc.entrySet()) { String k = e.getKey(); // Ignore the flag field if(StringUtil.equals(k, FLAGS_FIELD)) { continue; } // Read the flags for this field String[] flags = null; if(allFlags!=null) { String s = (String)allFlags.get(k); if(StringUtil.isNotEmpty(s)) { flags = StringUtil.splitString(s, ','); } } // Then convert the field Object v = toNotesObject(session,e.getValue(),flags); Item item = doc.replaceItemValue(k, v); if(getItemFilter()!=null && !getItemFilter().accept(item)) { item.remove(); } else { processItem(session, doc, item, flags); } } } protected Object toNotesObject(Session session, Object jsonObject, String[] flags) throws IOException, NotesException { if(jsonObject==null) { return null; } else if(jsonObject instanceof List<?>) { List<?> jsonArray = (List<?>)jsonObject; Vector<Object> v = new Vector<Object>(); for(int i=0; i<jsonArray.size(); i++) { v.add(toNotesObject(session,jsonArray.get(i),flags)); } return v; } else if(jsonObject instanceof String) { String s = (String)jsonObject; // 2013-06-17T14:31:44 if(s.length()==19 && s.charAt(4)=='-' && s.charAt(7)=='-'&& s.charAt(10)=='T' && s.charAt(13)==':' && s.charAt(16)==':') { try { Date dt = JsonGenerator.stringToDate(s); return session.createDateTime(dt); } catch (ParseException e) { // This is then a simple string... } } return jsonObject; } else if(jsonObject instanceof Number) { return jsonObject; } else { throw new IOException("Invalid Json type "+jsonObject.getClass()); } } protected Item processItem(Session session, Document document, Item item, String[] flags) throws IOException, NotesException { if(flags!=null) { if(StringUtil.contains(flags, FLAGS_NAMES)) { item.setNames(true); } if(StringUtil.contains(flags, FLAGS_READERS)) { item.setReaders(true); } if(StringUtil.contains(flags, FLAGS_AUTHORS)) { item.setAuthors(true); } } return item; } }