Java tutorial
/* * * MEDoKyService: * A web service component for learner modelling and learning recommendations. * Copyright (C) 2015 KTI, TUGraz, Contact: simone.kopeinik@tugraz.at * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * For more information about the GNU Affero General Public License see <http://www.gnu.org/licenses/>. * */ package at.tugraz.kmi.medokyservice.fca.util; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.Set; import java.util.concurrent.BlockingDeque; import at.tugraz.kmi.medokyservice.fca.db.DataObject; import at.tugraz.kmi.medokyservice.fca.db.Database; import at.tugraz.kmi.medokyservice.fca.db.FCAAbstract; import at.tugraz.kmi.medokyservice.fca.db.domainmodel.Course; import at.tugraz.kmi.medokyservice.fca.db.domainmodel.Domain; import at.tugraz.kmi.medokyservice.fca.db.domainmodel.FCAAttribute; import at.tugraz.kmi.medokyservice.fca.db.domainmodel.FCAItemMetadata; import at.tugraz.kmi.medokyservice.fca.db.domainmodel.FCAObject; import at.tugraz.kmi.medokyservice.fca.db.domainmodel.IncidenceMatrix; import at.tugraz.kmi.medokyservice.fca.db.domainmodel.LearningObject; import at.tugraz.kmi.medokyservice.fca.db.usermodel.User; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; public class ImportExport { private static final String SECTION_LO = "learningObjects"; private static final String SECTION_LO_L = "learningObjectsByLearners"; private static final String SECTION_O = "objects"; private static final String SECTION_A = "attributes"; private static final String SECTION_U = "users"; private static final String SECTION_D = "domains"; private static final String SECTION_M = "metadata"; private static final String SECTION_C = "courses"; private static final String ID = "id"; private static final String O_ID = "objectId"; private static final String E_UID = "externalUid"; private static final String E_CID = "externalCourseid"; private static final String CID = "creationId"; private static final String NAME = "name"; private static final String DESCRIPTION = "description"; private static final String OWNER = "owner"; private static final String DATA = "data"; private static final String MAPPING = "mapping"; private static final String GLOBAL = "global"; private static final String APPROVED = "approved"; private static final String PARTICIPANTS = "participants"; private String file; private boolean export; private Gson gson; private Random rand; private static JsonObject prepare(DataObject o) { JsonObject jso = new JsonObject(); jso.addProperty(ID, o.getId()); jso.addProperty(NAME, o.getName()); jso.addProperty(DESCRIPTION, o.getDescription()); return jso; } public ImportExport(String[] args) throws IllegalArgumentException { Params params = new Params(); JCommander cmd = new JCommander(params, args); rand = new Random(Long.parseLong("Bad5eed", 16)); if (params.file == null) { System.out.println("Import/Export FCA DB from/to JSON"); cmd.setProgramName("java -jar ImportExport.jar"); cmd.usage(); throw new IllegalArgumentException("File name unspecified!"); } this.gson = new Gson(); this.file = params.file; this.export = params.export; } private JsonElement users2JSON() { BlockingDeque<User> users = Database.getInstance().getAll(User.class); JsonObject block = new JsonObject(); for (User u : users) { JsonObject jso = prepare(u); jso.addProperty(E_UID, u.getExternalUid()); block.add(Long.toString(u.getId()), jso); } return block; } private JsonElement learningObjects2JSON() { BlockingDeque<LearningObject> lobjects = Database.getInstance().getAll(LearningObject.class); JsonObject block = new JsonObject(); for (LearningObject o : lobjects) { JsonObject jso = prepare(o); jso.addProperty(DATA, o.getData()); jso.addProperty(OWNER, o.getOwner().getId()); block.add(Long.toString(o.getId()), jso); } return block; } private <E extends FCAAbstract> JsonElement abstracts2JSon(Class<E> type) { BlockingDeque<E> objects = Database.getInstance().getAll(type); JsonObject block = new JsonObject(); for (E o : objects) { JsonObject jso = prepare(o); jso.addProperty(CID, o.getCreationId()); LinkedList<Long> loIds = new LinkedList<Long>(); LinkedList<Long> loByLearnerIds = new LinkedList<Long>(); for (LearningObject lo : o.getLearningObjects()) { loIds.add(lo.getId()); } for (LearningObject lo : o.getLearningObjectsByLearners()) { loByLearnerIds.add(lo.getId()); } jso.add(SECTION_LO, gson.toJsonTree(loIds, new TypeToken<List<Long>>() { }.getType())); jso.add(SECTION_LO_L, gson.toJsonTree(loByLearnerIds, new TypeToken<List<Long>>() { }.getType())); block.add(Long.toString(o.getId()), jso); } return block; } private JsonElement objects2JSON() { return abstracts2JSon(FCAObject.class); } private JsonElement attributes2JSON() { return abstracts2JSon(FCAAttribute.class); } private JsonElement metadata2JSON() { BlockingDeque<FCAItemMetadata> lobjects = Database.getInstance().getAll(FCAItemMetadata.class); JsonObject block = new JsonObject(); for (FCAItemMetadata o : lobjects) { JsonObject jso = prepare(o); jso.addProperty(O_ID, o.getItemID()); LinkedList<Long> loIds = new LinkedList<Long>(); for (LearningObject lo : o.getLearningObjects()) { if (lo != null) loIds.add(lo.getId()); } LinkedList<Long> loByLernerIds = new LinkedList<Long>(); for (LearningObject lo : o.getLearningObjectByLearner()) { if (lo != null) loByLernerIds.add(lo.getId()); } jso.add(SECTION_LO, gson.toJsonTree(loIds, new TypeToken<List<Long>>() { }.getType())); jso.add(SECTION_LO_L, gson.toJsonTree(loByLernerIds, new TypeToken<List<Long>>() { }.getType())); block.add(Long.toString(o.getId()), jso); } return block; } private JsonElement domains2JSON() { BlockingDeque<Domain> domains = Database.getInstance().getAll(Domain.class); JsonArray jsD = new JsonArray(); for (Domain d : domains) { IncidenceMatrix mat = d.getMapping(); Map<FCAObject, Set<FCAAttribute>> mapping = mat.getObjects(); JsonObject jso = prepare(d); JsonObject jsM = new JsonObject(); for (long mId : mat.getItemMetadata().keySet()) { jsM.addProperty(Long.toString(mId), mat.getItemMetadata().get(mId).getId()); } jso.add(SECTION_M, jsM); List<Long> ownerIDs = new LinkedList<Long>(); for (User o : d.getOwners()) { ownerIDs.add(o.getId()); } jso.add(OWNER, gson.toJsonTree(ownerIDs, new TypeToken<List<Long>>() { }.getType())); jso.addProperty(GLOBAL, d.isGlobal()); jso.addProperty(APPROVED, d.isApproved()); JsonObject jsMapping = new JsonObject(); for (FCAObject o : mapping.keySet()) { LinkedList<Long> aIds = new LinkedList<Long>(); for (FCAAttribute a : mapping.get(o)) { aIds.add(a.getId()); } jsMapping.add(Long.toString(o.getId()), gson.toJsonTree(aIds, new TypeToken<List<Long>>() { }.getType())); } jso.add(MAPPING, jsMapping); jsD.add(jso); } return jsD; } private JsonElement courses2JSON() { BlockingDeque<Course> courses = Database.getInstance().getAll(Course.class); JsonArray jsC = new JsonArray(); for (Course o : courses) { JsonObject jso = prepare(o); Set<Domain> domains = o.getDomains(); LinkedList<Long> dIds = new LinkedList<Long>(); for (Domain d : domains) dIds.add(d.getId()); jso.add(SECTION_D, gson.toJsonTree(dIds, new TypeToken<List<Long>>() { }.getType())); jso.addProperty(E_CID, o.getExternalCourseID()); List<Long> participants = new LinkedList<Long>(); for (User u : o.getParticipants()) participants.add(u.getId()); jso.add(PARTICIPANTS, gson.toJsonTree(participants, new TypeToken<List<Long>>() { }.getType())); jsC.add(jso); } return jsC; } private String export() { JsonObject output = new JsonObject(); output.add(SECTION_U, users2JSON()); output.add(SECTION_LO, learningObjects2JSON()); output.add(SECTION_O, objects2JSON()); output.add(SECTION_A, attributes2JSON()); output.add(SECTION_M, metadata2JSON()); output.add(SECTION_D, domains2JSON()); output.add(SECTION_C, courses2JSON()); return output.toString(); } private Map<Long, User> json2Users(JsonObject json) { HashMap<Long, User> users = new HashMap<Long, User>(); JsonObject block = json.get(SECTION_U).getAsJsonObject(); Set<Entry<String, JsonElement>> entries = block.entrySet(); for (Entry<String, JsonElement> u : entries) { JsonObject jsUser = u.getValue().getAsJsonObject(); System.out.println(jsUser.toString()); String uname; if (jsUser.has(NAME)) uname = jsUser.get(NAME).getAsString(); else uname = ""; String uDescr; if (jsUser.has(DESCRIPTION)) uDescr = jsUser.get(DESCRIPTION).getAsString(); else uDescr = ""; String externalUID; if (jsUser.has(E_UID)) externalUID = jsUser.get(E_UID).getAsString(); else externalUID = ""; User user = new User(externalUID, uname, uDescr); users.put(Long.parseLong(u.getKey()), user); } return users; } private Map<Long, LearningObject> json2LearningObjects(JsonObject json, Map<Long, User> users) { HashMap<Long, LearningObject> learningObjects = new HashMap<Long, LearningObject>(); JsonObject block = json.get(SECTION_LO).getAsJsonObject(); Set<Entry<String, JsonElement>> entries = block.entrySet(); for (Entry<String, JsonElement> lo : entries) { JsonObject jsLo = lo.getValue().getAsJsonObject(); User owner; try { owner = users.get(Long.parseLong(jsLo.get(OWNER).getAsString())); } catch (Exception e) { owner = null; } LearningObject learningObject = new LearningObject(jsLo.get(NAME).getAsString(), jsLo.get(DESCRIPTION).getAsString(), jsLo.get(DATA).getAsString(), owner); learningObjects.put(Long.parseLong(lo.getKey()), learningObject); } return learningObjects; } @SuppressWarnings("unchecked") private <E extends FCAAbstract> Map<Long, E> json2Absctract(JsonObject json, Map<Long, LearningObject> learningObjects, Class<E> type) { HashMap<Long, E> objects = new HashMap<Long, E>(); JsonObject block = null; if (type == FCAObject.class) block = json.get(SECTION_O).getAsJsonObject(); else if (type == FCAAttribute.class) block = json.get(SECTION_A).getAsJsonObject(); Set<Entry<String, JsonElement>> entries = block.entrySet(); for (Entry<String, JsonElement> o : entries) { JsonObject jsO = o.getValue().getAsJsonObject(); E object; String creationId; if (!jsO.has(CID)) { double num = rand.nextDouble() * 10000; int val = (int) num; creationId = Integer.toString(val, 16); } else creationId = jsO.get(CID).getAsString(); if (type == FCAObject.class) object = (E) new FCAObject(jsO.get(NAME).getAsString(), jsO.get(DESCRIPTION).getAsString(), creationId); else object = (E) new FCAAttribute(jsO.get(NAME).getAsString(), jsO.get(DESCRIPTION).getAsString(), creationId); Set<LearningObject> lObjs = new HashSet<LearningObject>(); Set<LearningObject> lObjsByLearner = new HashSet<LearningObject>(); Iterator<JsonElement> lOs = jsO.getAsJsonArray(SECTION_LO).iterator(); while (lOs.hasNext()) { LearningObject lo = learningObjects.get((lOs.next().getAsLong())); if (lo != null) lObjs.add(lo); } try { Iterator<JsonElement> lOsByLearner = jsO.getAsJsonArray(SECTION_LO_L).iterator(); while (lOsByLearner.hasNext()) { LearningObject lo = learningObjects.get((lOsByLearner.next().getAsLong())); if (lo != null) lObjsByLearner.add(lo); } } catch (Exception notAnError) { } clean(lObjsByLearner); object.setLearningObjectsByLearners(lObjsByLearner); clean(lObjs); object.setLearningObjects(lObjs); objects.put(Long.parseLong(o.getKey()), object); } return objects; } private Map<Long, FCAObject> json2Objects(JsonObject json, Map<Long, LearningObject> learningObjects) { return json2Absctract(json, learningObjects, FCAObject.class); } private Map<Long, FCAAttribute> json2Attributes(JsonObject json, Map<Long, LearningObject> learningObjects) { return json2Absctract(json, learningObjects, FCAAttribute.class); } private Map<Long, FCAItemMetadata> json2Metadata(JsonObject json, Map<Long, LearningObject> learningObjects) { Map<Long, FCAItemMetadata> result = new HashMap<Long, FCAItemMetadata>(); JsonObject jsM = json.get(SECTION_M).getAsJsonObject(); for (Entry<String, JsonElement> entry : jsM.entrySet()) { JsonObject val = entry.getValue().getAsJsonObject(); JsonArray arr = val.get(SECTION_LO).getAsJsonArray(); LinkedHashSet<LearningObject> l_objsByLearner = new LinkedHashSet<LearningObject>(); try { JsonArray arrByLearner = val.get(SECTION_LO_L).getAsJsonArray(); for (JsonElement loID : arrByLearner) l_objsByLearner.add(learningObjects.get(loID.getAsLong())); } catch (Exception notAnError) { } LinkedHashSet<LearningObject> l_objs = new LinkedHashSet<LearningObject>(); for (JsonElement loID : arr) l_objs.add(learningObjects.get(loID.getAsLong())); clean(l_objs); clean(l_objsByLearner); result.put(Long.parseLong(entry.getKey()), new FCAItemMetadata(val.get(DESCRIPTION).getAsString(), val.get(O_ID).getAsLong(), l_objs, l_objsByLearner)); } return result; } private Map<Long, Domain> json2Domains(JsonObject json, Map<Long, FCAObject> objects, Map<Long, FCAAttribute> attributes, Map<Long, User> users, Map<Long, FCAItemMetadata> metadata) { Iterator<JsonElement> jsD = json.getAsJsonArray(SECTION_D).iterator(); HashMap<Long, Domain> domains = new HashMap<Long, Domain>(); while (jsD.hasNext()) { JsonObject d = jsD.next().getAsJsonObject(); IncidenceMatrix mat = new IncidenceMatrix(d.get(NAME).getAsString(), d.get(DESCRIPTION).getAsString()); Set<Entry<String, JsonElement>> mapping = d.get(MAPPING).getAsJsonObject().entrySet(); JsonObject objMeta = d.get(SECTION_M).getAsJsonObject(); for (Entry<String, JsonElement> map : mapping) { FCAObject object = objects.get(Long.parseLong(map.getKey())); FCAItemMetadata meta = metadata.get(objMeta.get(map.getKey()).getAsLong()); System.out.println(object.getName()); object.setLearningObjects(meta.getLearningObjects()); object.setLearningObjectsByLearners(meta.getLearningObjectByLearner()); String descr = object.getDescription(); object.setDescription(meta.getDescription()); mat.storeMetadata(object); object.setDescription(descr); Iterator<JsonElement> atts = map.getValue().getAsJsonArray().iterator(); HashSet<FCAAttribute> attribs = new HashSet<FCAAttribute>(); while (atts.hasNext()) { long id = atts.next().getAsLong(); FCAAttribute attr = attributes.get(id); attribs.add(attr); meta = metadata.get(objMeta.get(Long.toString(id)).getAsLong()); attr.setLearningObjects(meta.getLearningObjects()); descr = attr.getDescription(); attr.setDescription(meta.getDescription()); mat.storeMetadata(attr); attr.setDescription(descr); } mat.add(object, attribs); } boolean global = (d.get(GLOBAL) == null) ? false : d.get(GLOBAL).getAsBoolean(); Domain domain; // compat try { domain = new Domain(mat.getName(), mat.getDescription(), mat, users.get(d.get(OWNER).getAsLong()), global); } catch (Exception e) { // new format Set<User> owners = new HashSet<User>(); Iterator<JsonElement> uIds = d.getAsJsonArray(OWNER).iterator(); while (uIds.hasNext()) owners.add(users.get(uIds.next().getAsLong())); domain = new Domain(mat.getName(), mat.getDescription(), mat, owners, global); } if (d.get(APPROVED) == null) { domain.setApproved(true); } else { domain.setApproved(d.get(APPROVED).getAsBoolean()); } domains.put(d.get(ID).getAsLong(), domain); } return domains; } private Set<Course> json2Courses(JsonObject json, Map<Long, Domain> domains, Map<Long, User> users) { Set<Course> courses = new HashSet<Course>(); Iterator<JsonElement> jsC = json.getAsJsonArray(SECTION_C).iterator(); while (jsC.hasNext()) { JsonObject c = jsC.next().getAsJsonObject(); Iterator<JsonElement> domainIds = c.getAsJsonArray(SECTION_D).iterator(); Set<Domain> ddomains = new HashSet<Domain>(); while (domainIds.hasNext()) { Domain domain = domains.get(domainIds.next().getAsLong()); ddomains.add(domain); } Iterator<JsonElement> userIds = c.getAsJsonArray(PARTICIPANTS).iterator(); Set<User> uusers = new HashSet<User>(); while (userIds.hasNext()) { User u = users.get(userIds.next().getAsLong()); uusers.add(u); } Course course = new Course(c.get(NAME).getAsString(), c.get(DESCRIPTION).getAsString(), c.get(E_CID).getAsString()); for (Domain d : ddomains) { course.addDomain(d); } for (User u : uusers) course.addParticipant(u); courses.add(course); } return courses; } private void imPort(JsonObject json) throws Exception { Database.getInstance().clear(); Map<Long, User> users = json2Users(json); Database.getInstance().putAll(users.values(), false); Map<Long, LearningObject> learningObjects = json2LearningObjects(json, users); Database.getInstance().putAll(learningObjects.values(), false); Map<Long, FCAObject> objects = json2Objects(json, learningObjects); Database.getInstance().putAll(objects.values(), false); Map<Long, FCAAttribute> attributes = json2Attributes(json, learningObjects); Database.getInstance().putAll(attributes.values(), false); Map<Long, FCAItemMetadata> metadata = json2Metadata(json, learningObjects); Database.getInstance().putAll(metadata.values(), false); Map<Long, Domain> domains = json2Domains(json, objects, attributes, users, metadata); for (Domain domain : domains.values()) { Database.getInstance().putAll(domain.getFormalContext().getConcepts(), false); } Database.getInstance().putAll(domains.values(), false); Database.getInstance().putAll(json2Courses(json, domains, users), false); Database.getInstance().save(); } private void clean(Set<LearningObject> data) { data.remove(null); } private class Params { @Parameter private List<String> parameters = new ArrayList<String>(); @Parameter(names = { "-f", "--file" }, description = "Source/Desitnation File") private String file; @Parameter(names = { "-e", "--export" }, description = "Export mode, the FCA DB file needs to be located at webapps/at.tugraz.kmi.medoky.fca.db" + " -- If not set data will be imported to webapps/at.tugraz.kmi.medoky.fca.db") private boolean export = false; } public static void main(String[] args) { try { ImportExport ie = new ImportExport(args); File io = new File(ie.file); if (ie.export) { BufferedWriter out = new BufferedWriter(new FileWriter(io, false)); Gson gson = new GsonBuilder().setPrettyPrinting().create(); JsonParser jp = new JsonParser(); JsonElement je = jp.parse(ie.export()); out.write(gson.toJson(je)); out.close(); } else { BufferedReader in = new BufferedReader(new FileReader(io)); ie.imPort(new JsonParser().parse(in).getAsJsonObject()); in.close(); } } catch (Exception e) { System.err.println("Error: " + e.getLocalizedMessage()); e.printStackTrace(); } } }