/* * Copyright (C) 2015 Jan Pokorsky * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package cz.cas.lib.proarc.common.dao.empiredb; import cz.cas.lib.proarc.common.dao.WorkflowMaterialDao; import cz.cas.lib.proarc.common.workflow.model.DigitalMaterial; import cz.cas.lib.proarc.common.workflow.model.FolderMaterial; import cz.cas.lib.proarc.common.workflow.model.Job; import cz.cas.lib.proarc.common.workflow.model.Material; import cz.cas.lib.proarc.common.workflow.model.MaterialType; import cz.cas.lib.proarc.common.workflow.model.MaterialFilter; import cz.cas.lib.proarc.common.workflow.model.MaterialView; import cz.cas.lib.proarc.common.workflow.model.PhysicalMaterial; import cz.cas.lib.proarc.common.workflow.model.Task; import cz.cas.lib.proarc.common.workflow.profile.Way; import java.math.BigDecimal; import java.sql.Connection; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.apache.empire.data.DataType; import org.apache.empire.db.DBColumn; import org.apache.empire.db.DBCommand; import org.apache.empire.db.DBJoinType; import org.apache.empire.db.DBQuery; import org.apache.empire.db.DBReader; import org.apache.empire.db.DBRecord; import org.apache.empire.db.DBRecordData; import org.apache.empire.db.DBTable; import org.apache.empire.db.exceptions.RecordNotFoundException; import org.apache.empire.db.expr.compare.DBCompareExpr; /** * * @author Jan Pokorsky */ public class EmpireWorkflowMaterialDao extends EmpireDao implements WorkflowMaterialDao { public EmpireWorkflowMaterialDao(ProarcDatabase db) { super(db); } @Override public <T extends Material> T create(MaterialType type) { Material m = type == MaterialType.FOLDER ? new FolderMaterial() : type == MaterialType.DIGITAL_OBJECT ? new DigitalMaterial() : type == MaterialType.PHYSICAL_DOCUMENT ? new PhysicalMaterial() : null; return (T) m; } @Override public <T extends Material> T find(BigDecimal id) { DBRecord record = new DBRecord(); try { record.read(db.tableWorkflowMaterial, id, getConnection()); MaterialType type = MaterialType.valueOf(record.getString(db.tableWorkflowMaterial.type)); Material m = create(type); record.getBeanProperties(m); return (T) fetchCustom(m); } catch (RecordNotFoundException ex) { return null; } finally { record.close(); } } @Override public Job findJob(Material m) { DBCommand cmd = db.createCommand(); cmd.select(db.tableWorkflowJob.getColumns()); cmd.selectDistinct(); cmd.join(db.tableWorkflowMaterialInTask.taskId, db.tableWorkflowTask.id); cmd.join(db.tableWorkflowTask.jobId, db.tableWorkflowJob.id); cmd.where(db.tableWorkflowMaterialInTask.materialId.is(m.getId())); DBReader reader = new DBReader(); try { reader.open(cmd, getConnection()); for (Iterator<DBRecordData> it = reader.iterator(1); it.hasNext();) { DBRecordData rec = it.next(); Job job = new Job(); rec.getBeanProperties(job); return job; } return null; } finally { reader.close(); } } private <T extends Material> T fetchCustom(Material m) { DBTable t = getMaterialTable(m.getType()); DBRecord record = new DBRecord(); try { record.read(t, m.getId(), getConnection()); record.getBeanProperties(m); return (T) m; } catch (RecordNotFoundException ex) { return null; } finally { record.close(); } } @Override public List<MaterialView> view(MaterialFilter filter) { DBCommand cmd = db.createCommand(); cmd.select(db.tableWorkflowMaterial.getColumns()); cmd.select(db.tableWorkflowFolder.path); cmd.select(db.tableWorkflowDigObj.pid); List<DBColumn> physicalSelections = new ArrayList<DBColumn>(db.tableWorkflowPhysicalDoc.getColumns()); physicalSelections.remove(db.tableWorkflowPhysicalDoc.materialId); cmd.select(physicalSelections); cmd.join(db.tableWorkflowMaterial.id, db.tableWorkflowFolder.materialId, DBJoinType.LEFT); cmd.join(db.tableWorkflowMaterial.id, db.tableWorkflowDigObj.materialId, DBJoinType.LEFT); cmd.join(db.tableWorkflowMaterial.id, db.tableWorkflowPhysicalDoc.materialId, DBJoinType.LEFT); if (filter.getId() != null) { cmd.where(db.tableWorkflowMaterial.id.is(filter.getId())); } if (filter.getTaskId() != null) { cmd.select(db.tableWorkflowMaterialInTask.taskId); cmd.select(db.tableWorkflowMaterialInTask.way); cmd.join(db.tableWorkflowMaterial.id, db.tableWorkflowMaterialInTask.materialId); cmd.addWhereConstraints(Collections.<DBCompareExpr>singletonList( db.tableWorkflowMaterialInTask.taskId.is(filter.getTaskId()) )); } else if (filter.getJobId() != null) { DBCommand subcmd = db.createCommand(); subcmd.select(db.tableWorkflowMaterialInTask.materialId); subcmd.selectDistinct(); subcmd.join(db.tableWorkflowMaterialInTask.taskId, db.tableWorkflowTask.id); subcmd.where(db.tableWorkflowTask.jobId.is(filter.getJobId())); DBQuery materialIds = new DBQuery(subcmd); cmd.addWhereConstraints(Collections.<DBCompareExpr>singletonList( db.tableWorkflowMaterial.id.in(materialIds.findQueryColumn(db.tableWorkflowMaterialInTask.materialId)) )); cmd.select(db.getValueExpr(filter.getJobId(), DataType.DECIMAL).as(db.tableWorkflowTask.jobId)); } else { cmd.select(db.tableWorkflowMaterialInTask.taskId); cmd.select(db.tableWorkflowMaterialInTask.way); cmd.join(db.tableWorkflowMaterial.id, db.tableWorkflowMaterialInTask.materialId); } EmpireUtils.addOrderBy(cmd, filter.getSortBy(), db.tableWorkflowMaterial.id, false); DBReader reader = new DBReader(); try { reader.open(cmd, getConnection()); if (!reader.skipRows(filter.getOffset())) { return Collections.emptyList(); } ArrayList<MaterialView> viewItems = new ArrayList<MaterialView>(filter.getMaxCount()); for (Iterator<DBRecordData> it = reader.iterator(filter.getMaxCount()); it.hasNext();) { DBRecordData rec = it.next(); MaterialView view = new MaterialView(); rec.getBeanProperties(view); viewItems.add(view); } return viewItems; } finally { reader.close(); } } @Override public void update(Material m) { Connection c = getConnection(); DBRecord r = new DBRecord(); boolean isNew = m.getId() == null; if (isNew) { r.create(db.tableWorkflowMaterial); } else { r.read(db.tableWorkflowMaterial, m.getId(), c); } r.setBeanValues(m); r.update(c); r.getBeanProperties(m); updateCustom(m, isNew, c); } void updateCustom(Material m, boolean isNew, Connection c) { DBTable t = getMaterialTable(m.getType()); DBRecord r = new DBRecord(); if (isNew) { r.create(t); } else { r.read(t, m.getId(), c); } r.setBeanValues(m); r.update(c); } @Override public void addTaskReference(Material m, Task t, Way way) { DBRecord r = new DBRecord(); r.create(db.tableWorkflowMaterialInTask); r.setValue(db.tableWorkflowMaterialInTask.materialId, m.getId()); r.setValue(db.tableWorkflowMaterialInTask.taskId, t.getId()); r.setValue(db.tableWorkflowMaterialInTask.way, way.name()); r.update(getConnection()); } DBTable getMaterialTable(MaterialType type) { return type == MaterialType.FOLDER ? db.tableWorkflowFolder : type == MaterialType.DIGITAL_OBJECT ? db.tableWorkflowDigObj : type == MaterialType.PHYSICAL_DOCUMENT ? db.tableWorkflowPhysicalDoc : null; } }