package frostillicus.xsp.darwino.model; import static frostillicus.xsp.model.ModelUtils.stringSet; import java.lang.reflect.Field; import java.sql.SQLException; import java.text.MessageFormat; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; import javax.faces.model.DataModel; import javax.persistence.Table; import org.openntf.domino.Item; import org.openntf.domino.Session; import com.darwino.commons.json.JsonException; import com.darwino.commons.json.JsonObject; import com.darwino.commons.util.StringUtil; import com.darwino.jsonstore.Database; import com.darwino.jsonstore.Document; import com.darwino.jsonstore.Store; import com.ibm.xsp.model.FileRowData; import frostillicus.xsp.darwino.SqlContextApplicationListener; import frostillicus.xsp.model.AbstractModelObject; import frostillicus.xsp.model.ModelUtils; import frostillicus.xsp.util.FrameworkUtils; /** * @author Jesse Gallagher * @since 1.0.0 */ public abstract class AbstractDarwinoModel extends AbstractModelObject { private static final long serialVersionUID = 1L; private String connectionBeanName_; private String databaseId_; private String instanceId_; private String storeId_; private String documentId_; private boolean category_; private JsonObject docJson_; /* ****************************************************************************** * Model initialization ********************************************************************************/ public void initFromStore(String connectionBeanName, final Store store) throws JsonException { connectionBeanName_ = connectionBeanName; storeId_ = store.getId(); databaseId_ = store.getDatabase().getId(); instanceId_ = store.getDatabase().getInstance().getId(); documentId_ = ""; //$NON-NLS-1$ category_ = false; // Look for an @Table annotation to set the form Table tableAnnotation = getClass().getAnnotation(Table.class); if(tableAnnotation != null) { setValueImmediate("form", tableAnnotation.name()); //$NON-NLS-1$ } docJson_ = new JsonObject(); } public void initFromDocument(String connectionBeanName, final Document doc) throws JsonException { connectionBeanName_ = connectionBeanName; storeId_ = doc.getStore().getId(); databaseId_ = doc.getStore().getDatabase().getId(); instanceId_ = doc.getStore().getDatabase().getInstance().getId(); documentId_ = doc.getUnid(); category_ = false; category_ = false; docJson_ = (JsonObject)doc.getJson(); } @Override public boolean delete() { if (category()) { throw new UnsupportedOperationException("Categories cannot be deleted"); } try { if(queryDelete()) { if (isNew()) { return false; } getDatabase().getStore(storeId_).deleteDocument(documentId_); } return false; } catch (Exception ne) { ModelUtils.publishException(ne); return false; } } @Override public void deleteAttachment(Object key, String attachmentName) { } @Override public List<FileRowData> getAttachmentList(Object key) { return null; } @Override public String getId() { return documentId_; } @Override public boolean category() { return category_; } @Override public int columnIndentLevel() { return 0; } @Override public String viewRowPosition() { return null; } @Override public DataModel getAttachmentData(Object key) { return null; } @Override public List<FileRowData> getEmbeddedImageList(Object key) { return null; } @Override public Set<String> columnPropertyNames() { return Collections.emptySet(); } @Override public Date lastModified() { if(isNew()) { return null; } try { return document().getLastModificationDate(); } catch(JsonException e) { throw new RuntimeException(e); } catch(SQLException e) { throw new RuntimeException(e); } } @Override public Date created() { if(isNew()) { return null; } try { return document().getCreationDate(); } catch(JsonException e) { throw new RuntimeException(e); } catch(SQLException e) { throw new RuntimeException(e); } } @Override public List<String> modifiedBy() { if(isNew()) { return Collections.emptyList(); } try { return Arrays.asList(document().getLastModificationUser()); } catch(JsonException e) { throw new RuntimeException(e); } catch(SQLException e) { throw new RuntimeException(e); } } @Override protected Object getValueImmediate(Object keyObject) { return docJson_.get(keyObject); } @Override protected void setValueImmediate(Object keyObject, Object value) { docJson_.put(StringUtil.toString(keyObject), value); } @Override public boolean save() { if (category()) { throw new UnsupportedOperationException("Categories cannot be saved"); //$NON-NLS-1$ } try { if (querySave()) { if(!super.save()) { return false; } if(isNew()) { setValueImmediate("$$ModelCreatedAt", new Date()); //$NON-NLS-1$ setValueImmediate("$$ModelCreatedBy", FrameworkUtils.getUserName()); //$NON-NLS-1$ } setValueImmediate("$$ModelModifiedAt", new Date()); //$NON-NLS-1$ setValueImmediate("$$ModelModifiedBy", FrameworkUtils.getUserName()); //$NON-NLS-1$ Document doc = document(true); doc.save(); if(documentId_.isEmpty()) { documentId_ = doc.getUnid(); } postSave(); return true; } return false; } catch (Exception ne) { ModelUtils.publishException(ne); return false; } } /* ********************************************************************** * Misc. leftovers ************************************************************************/ public Document document() throws JsonException, SQLException { return document(false); } public Document document(boolean applyChanges) throws JsonException, SQLException { Database database = getDatabase(); Document doc = null; if(isNew()) { doc = database.getStore(storeId_).newDocument(); } else { doc = database.getStore(storeId_).loadDocument(documentId_); } if(applyChanges) { doc.setJson(docJson_.makeCopy()); } return doc; } /* ****************************************************************************** * Internal utility methods ********************************************************************************/ protected Database getDatabase() throws SQLException, JsonException { return SqlContextApplicationListener.getDatabase(connectionBeanName_, instanceId_, databaseId_); } }