/******************************************************************************* * Copyright 2011 Alex 'Ript' Malyshev <alexript@gmail.com> * * 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 net.autosauler.ballance.server.model; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.script.ScriptException; import net.autosauler.ballance.server.mongodb.Database; import net.autosauler.ballance.server.vm.DocumentWrapper; import net.autosauler.ballance.shared.Description; import net.autosauler.ballance.shared.Field; import net.autosauler.ballance.shared.Name; import net.autosauler.ballance.shared.Table; import net.autosauler.ballance.shared.UserRole; import net.autosauler.ballance.shared.datatypes.DataTypes; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import com.allen_sauer.gwt.log.client.Log; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; /** * The Class AbstractDocument. * * @author alexript */ public class AbstractDocument extends AbstractStructuredData implements IScriptableObject { /** The Constant fieldname_active. */ private static final String fieldname_active = "active"; /** The Constant fieldname_activationdate. */ private static final String fieldname_activationdate = "activationdate"; /** The Constant fieldname_parentdoc. */ private static final String fieldname_parentdoc = "pardoc"; /** The Constant fieldname_parentdocname. */ private static final String fieldname_parentdocname = "pardocname"; public static AbstractDocument getInstance(String docname, UserRole role, String domain) { if (docname.startsWith("document.")) { Structures s = new Structures(domain); Description d = s.getDescription(docname); if (role.hasAccess(new UserRole(d.getRole()))) { String name = docname.replace("document.", ""); return new AbstractDocument(name, domain); } } return null; } public static AbstractDocument getInstance(String docname, UserRole role, String domain, Long number) { if (docname.startsWith("document.")) { Structures s = new Structures(domain); Description d = s.getDescription(docname); if (role.hasAccess(new UserRole(d.getRole()))) { String name = docname.replace("document.", ""); return new AbstractDocument(name, domain, number); } } return null; } public static AbstractDocument getInstance(String docname, UserRole role, String domain, String login) { if (docname.startsWith("document.")) { Structures s = new Structures(domain); Description d = s.getDescription(docname); if (role.hasAccess(new UserRole(d.getRole()))) { String name = docname.replace("document.", ""); return new AbstractDocument(name, domain, login); } } return null; } private boolean useunactive = true; /** The tables. */ private HashMap<String, DocumentTablePart> tables; private Description structuredescription; /** * Instantiates a new document. * * @param name * the name * @param domain * the domain */ public AbstractDocument(String name, String domain) { super("doc", name, domain); initTableParts(); } /** * Instantiates a new document. * * @param name * the name * @param domain * the domain * @param number * the number */ public AbstractDocument(String name, String domain, Long number) { super("doc", name, domain); initTableParts(); get(number); } /** * Instantiates a new document. * * @param name * the name * @param domain * the domain * @param username * the username */ public AbstractDocument(String name, String domain, String username) { super("doc", name, domain); initTableParts(); setUsername(username); } /** * Activation. */ public void activation() { if (!isActive()) { if (onActivation()) { Scripts script = new Scripts(this, getDomain(), getUsername(), "document." + getSuffix()); try { script.call("OnActivate", new DocumentWrapper(this)); } catch (ScriptException e) { Log.error(e.getMessage()); } catch (NoSuchMethodException e) { Log.error(e.getMessage()); } setActive(true); setActivationdate(new Date()); // document activation } } } /* * (non-Javadoc) * * @see * net.autosauler.ballance.server.model.AbstractStructuredData#addFindAllOrders * ( com.mongodb.BasicDBObject) */ @Override protected void addFindAllOrders(BasicDBObject o) { return; } /* * (non-Javadoc) * * @see net.autosauler.ballance.server.model.AbstractStructuredData# * addFindAllQueryParameters (com.mongodb.BasicDBObject) */ @Override protected void addFindAllQueryParameters(BasicDBObject q) { if (!useunactive) { q.put(fieldname_active, true); } return; } /* * (non-Javadoc) * * @see net.autosauler.ballance.server.model.AbstractStructuredData# * addFindLastNumberParams(com.mongodb.BasicDBObject) */ @Override protected void addFindLastNumberParams(BasicDBObject w) { return; } /* * (non-Javadoc) * * @see net.autosauler.ballance.server.model.AbstractStructuredData# * addGetRecordParams(com.mongodb.BasicDBObject) */ @Override protected void addGetRecordParams(BasicDBObject query) { return; } public Set<Long> findAll(boolean withunactive) { useunactive = withunactive; return findAll(); } /** * Find all childs. * * @param docname * the docname * @return the sets the */ public Set<Long> findAllChilds(String docname) { Set<Long> numbers = new HashSet<Long>(); DB db = Database.get(getDomain()); if (db != null) { Database.retain(); DBCollection coll = db.getCollection("doc_" + docname); BasicDBObject q = new BasicDBObject(); BasicDBObject w = new BasicDBObject(); q.put(fieldname_domain, getDomain()); q.put(fieldname_trash, false); q.put(fieldname_parentdoc, getNumber()); q.put(fieldname_parentdocname, getSuffix()); w.put("$query", q); BasicDBObject o = new BasicDBObject(); o.put(fieldname_number, 1); addFindAllOrders(o); w.put("$orderby", o); DBCursor cur = coll.find(w); while (cur.hasNext()) { DBObject myDoc = cur.next(); numbers.add((Long) myDoc.get(fieldname_number)); } Database.release(); } return numbers; } /* * (non-Javadoc) * * @see * net.autosauler.ballance.server.model.IScriptableObject#generateDefaultScript * () */ @Override public String generateDefaultScript() { StringBuilder sb = new StringBuilder(); sb.append("import java.lang\nimport com.allen_sauer.gwt.log.client.Log\n\n"); sb.append("function OnCreate(document)\n Log.error('method OnCreate not defined')\nend\n\n"); sb.append("function OnTrash(document)\n Log.error('method OnTrash not defined')\nend\n\n"); sb.append("function OnRestore(document)\n Log.error('method OnRestore not defined')\nend\n\n"); sb.append("function OnUpdate(document)\n Log.error('method OnUpdate not defined')\nend\n\n"); sb.append("function OnActivate(document)\n Log.error('method OnActivate not defined')\nend\n\n"); sb.append("function OnUnactivate(document)\n Log.error('method OnUnactivate not defined')\nend\n\n"); // Set<String> names = struct.getNames(); // Iterator<String> i = names.iterator(); // while (i.hasNext()) { // String n = i.next(); // String nn = Character.toUpperCase(n.charAt(0)) + n.substring(1); // String name = "On" + nn + "Change"; // sb.append("// must return HashTable\n"); // sb.append("function " + name + "(hashTable)\n Log.error('method " // + name + " not defined')\n return hashTable\nend\n\n"); // } sb.append("// must return HashTable\n"); sb.append("function OnChange(fieldname, hashTable)\n return hashTable\nend\n\n"); if (hasTables()) { sb.append("// must return HashTable\n"); sb.append("function OnChangeTable" + "(tablename, fieldname, hashTable)\n return hashTable\nend\n\n"); // names = tables.keySet(); // i = names.iterator(); // while (i.hasNext()) { // String name = i.next(); // // String prefix = "On" + Character.toUpperCase(name.charAt(0)) // + name.substring(1); // // DocumentTablePart part = tables.get(name); // Set<String> fields = part.struct.getNames(); // Iterator<String> j = fields.iterator(); // while (j.hasNext()) { // String field = j.next(); // String nn = Character.toUpperCase(field.charAt(0)) // + field.substring(1); // String method = prefix + nn + "Change"; // sb.append("// must return HashTable\n"); // sb.append("function " + method // + "(hashTable)\n Log.error('method " + method // + " not defined')\n return hashTable\nend\n\n"); // } // // } } return sb.toString(); } /** * Gets the. * * @param numbers * the numbers * @return the sets the */ public Set<HashMap<String, Object>> get(Set<Long> numbers) { Set<HashMap<String, Object>> set = new HashSet<HashMap<String, Object>>(); Iterator<Long> i = numbers.iterator(); while (i.hasNext()) { Long number = i.next(); AbstractDocument doc = new AbstractDocument(getSuffix(), getDomain(), number); if (doc != null) { set.add(doc.toMap()); } } return set; } /** * Gets the activationdate. * * @return the activationdate */ public Date getActivationdate() { return (Date) values.get(fieldname_activationdate); } public String getDocDescription(String lang) { Structures s = new Structures(getDomain()); Description d = s.getDescription("document." + getDocname()); Name n = d.getName(); return n.getName(lang); } public String getDocname() { return getSuffix(); } /** * Gets the part. * * @param name * the name * @return the part */ public DocumentTablePart getPart(String name) { if (tables.containsKey(name)) { return tables.get(name); } return null; } /** * Gets the table records. * * @param name * the name * @return the table records */ public Set<HashMap<String, Object>> getTableRecords(String name) { Set<HashMap<String, Object>> set = null; DocumentTablePart table = getPart(name); if (table != null) { set = table.getRecords(); } return set; } /** * Checks for tables. * * @return true, if successful */ public boolean hasTables() { return (tables != null) && !tables.isEmpty(); } /* * (non-Javadoc) * * @see net.autosauler.ballance.server.model.AbstractStructuredData# * initGlobalStructure() */ @Override protected void initGlobalStructure() { struct.add(fieldname_active, DataTypes.DT_BOOLEAN, new Boolean(false)); struct.add(fieldname_activationdate, DataTypes.DT_DATE, new Date()); struct.add(fieldname_parentdoc, DataTypes.DT_DOCUMENTRECORD, new Long( 0L)); struct.add(fieldname_parentdocname, DataTypes.DT_DOCUMENT, ""); } /* * (non-Javadoc) * * @see * net.autosauler.ballance.server.model.AbstractStructuredData#initStructure * () */ @Override protected void initStructure(String domain) { Structures s = new Structures(domain); structuredescription = s.getDescription("document." + getSuffix()); tables = new HashMap<String, DocumentTablePart>(); List<Field> fields = structuredescription.get(); Iterator<Field> i = fields.iterator(); while (i.hasNext()) { Field f = i.next(); struct.add(f.getFieldname(), f.getType(), f.getDefval()); } } private void initTableParts() { List<Table> doctables = structuredescription.getTables(); Iterator<Table> j = doctables.iterator(); while (j.hasNext()) { Table t = j.next(); DocumentTablePart part = new DocumentTablePart(t.getName(), getDomain()); part.setDocnum(getNumber()); tables.put(t.getName(), part); } } /** * Checks if is active. * * @return the active */ public boolean isActive() { return (Boolean) values.get(fieldname_active); } /** * On activation. * * @return true, if successful */ protected boolean onActivation() { return true; } /* * (non-Javadoc) * * @see * net.autosauler.ballance.server.model.AbstractStructuredData#onCreate() */ @Override protected void onCreate() { Scripts script = new Scripts(this, getDomain(), getUsername(), "document." + getSuffix()); try { script.call("OnCreate", new DocumentWrapper(this)); } catch (ScriptException e) { Log.error(e.getMessage()); } catch (NoSuchMethodException e) { Log.error(e.getMessage()); } } /* * (non-Javadoc) * * @see net.autosauler.ballance.server.model.AbstractStructuredData#onDump() */ @Override protected StringBuilder onDump() { if (!hasTables()) { return null; } StringBuilder sb = new StringBuilder(); sb.append("<tables>\n"); Set<String> names = tables.keySet(); Iterator<String> i = names.iterator(); while (i.hasNext()) { String name = i.next(); DocumentTablePart part = tables.get(name); sb.append(part.dump()); } sb.append("</tables>\n"); return sb; } /* * (non-Javadoc) * * @see * net.autosauler.ballance.server.model.AbstractStructuredData#onGetRecord * (java.lang.Long) */ @Override protected void onGetRecord(Long number) { Set<String> names = tables.keySet(); Iterator<String> i = names.iterator(); while (i.hasNext()) { String name = i.next(); tables.get(name).setDocnum(number); } } /* * (non-Javadoc) * * @see * net.autosauler.ballance.server.model.AbstractStructuredData#onInitDbStruct * (com .mongodb.BasicDBObject, com.mongodb.DBCollection) */ @Override protected void onInitDbStruct(final BasicDBObject i, final DBCollection coll) { i.put(fieldname_active, 1); coll.createIndex(i); } /** * On restore. * * @param dump * the dump */ @Override protected void onRestore(Element dump) { NodeList tablessets = dump.getElementsByTagName("tables"); if (tablessets.getLength() > 0) { for (int i = 0; i < tablessets.getLength(); i++) { Element tablesset = (Element) tablessets.item(i); NodeList tablenodes = tablesset.getElementsByTagName("doctab"); if (tablenodes.getLength() > 0) { for (int j = 0; j < tablenodes.getLength(); j++) { Element tablenode = (Element) tablenodes.item(i); String name = tablenode.getAttribute("name"); DocumentTablePart p = new DocumentTablePart(name, getDomain()); p.restore(tablenode); } } } } } /** * On un activation. * * @return true, if successful */ protected boolean onUnActivation() { return true; } /* * (non-Javadoc) * * @see * net.autosauler.ballance.server.model.AbstractStructuredData#onUpdate() */ @Override protected void onUpdate() { Scripts script = new Scripts(this, getDomain(), getUsername(), "document." + getSuffix()); try { script.call("OnUpdate", new DocumentWrapper(this)); } catch (ScriptException e) { Log.error(e.getMessage()); } catch (NoSuchMethodException e) { Log.error(e.getMessage()); } } /* * (non-Javadoc) * * @see * net.autosauler.ballance.server.model.AbstractStructuredData#restore() */ @Override public void restore() { super.restore(); Scripts script = new Scripts(this, getDomain(), getUsername(), "document." + getSuffix()); try { script.call("OnRestore", new DocumentWrapper(this)); } catch (ScriptException e) { Log.error(e.getMessage()); } catch (NoSuchMethodException e) { Log.error(e.getMessage()); } } /** * Save table records. * * @param username * the username * @param tableparts * the tableparts * @return true, if successful */ public boolean saveTableRecords(String username, HashMap<String, Set<HashMap<String, Object>>> tableparts) { boolean result = true; if (tableparts != null) { Long num = getNumber(); if (num.equals(0L)) { result = save(); num = getNumber(); } Set<String> names = tableparts.keySet(); Iterator<String> i = names.iterator(); while (i.hasNext()) { String name = i.next(); result = result && saveTableRecords(username, num, name, tableparts.get(name)); } } return result; } /** * Save table records. * * @param username * the username * @param docnumber * the docnumber * @param name * the name * @param set * the set * @return true, if successful */ public boolean saveTableRecords(String username, Long docnumber, String name, Set<HashMap<String, Object>> set) { boolean result = true; DocumentTablePart table = getPart(name); if (table != null) { result = table.updateRecords(username, docnumber, set); } return result; } /** * Sets the activationdate. * * @param activationdate * the activationdate to set */ public void setActivationdate(Date activationdate) { values.set(fieldname_activationdate, activationdate); } /** * Sets the active. * * @param active * the active to set */ public void setActive(boolean active) { values.set(fieldname_active, active); } /** * Sets the parent. * * @param d * the new parent */ public void setParent(AbstractDocument d) { values.set(fieldname_parentdocname, d.getSuffix()); values.set(fieldname_parentdoc, d.getNumber()); } /** * Sets the parent. * * @param docname * the docname * @param num * the new parent */ public void setParent(String docname, Long num) { values.set(fieldname_parentdocname, docname); values.set(fieldname_parentdoc, num); } /* * (non-Javadoc) * * @see net.autosauler.ballance.server.model.AbstractStructuredData#trash() */ @Override public void trash() { super.trash(); Scripts script = new Scripts(this, getDomain(), getUsername(), "document." + getSuffix()); try { script.call("OnTrash", new DocumentWrapper(this)); } catch (ScriptException e) { Log.error(e.getMessage()); } catch (NoSuchMethodException e) { Log.error(e.getMessage()); } } /** * Unactivation. */ public void unactivation() { if (isActive()) { if (onUnActivation()) { Scripts script = new Scripts(this, getDomain(), getUsername(), "document." + getSuffix()); try { script.call("OnUnactivate", new DocumentWrapper(this)); } catch (ScriptException e) { Log.error(e.getMessage()); } catch (NoSuchMethodException e) { Log.error(e.getMessage()); } setActive(false); } } } }