/* * Copyright 2009-2012 by KNURT Systeme (http://www.knurt.de) * * Licensed under the Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://creativecommons.org/licenses/by-nc-sa/3.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 de.knurt.fam.core.persistence.dao.couchdb; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.jcouchdb.db.Response; import org.jcouchdb.document.DocumentInfo; import org.json.JSONException; import org.json.JSONObject; import org.svenson.JSONParseException; import de.knurt.fam.core.aspects.logging.FamLog; import de.knurt.fam.core.aspects.security.auth.FamAuth; import de.knurt.fam.core.model.config.Facility; import de.knurt.fam.core.model.persist.User; import de.knurt.fam.core.model.persist.booking.Booking; import de.knurt.fam.core.model.persist.document.Job; import de.knurt.fam.core.model.persist.document.JobDataProcessing; import de.knurt.fam.core.persistence.dao.FamJobsDao; import de.knurt.fam.core.persistence.dao.config.FacilityConfigDao; import de.knurt.fam.core.util.booking.JobDataProcessingVelocityParser; import de.knurt.heinzelmann.util.query.QueryString; import de.knurt.heinzelmann.util.query.QueryStringFactory; /** * dao for jobs of the fam * * @author Daniel Oltmanns <info@knurt.de> * @since 1.6.0 (11/23/20111) */ public class CouchDBDao4Jobs implements FamJobsDao { /** one and only instance of CouchDBDao4Jobs */ private volatile static CouchDBDao4Jobs me; /** construct CouchDBDao4Jobs */ private CouchDBDao4Jobs() { } /** * return the one and only instance of CouchDBDao4Jobs * * @return the one and only instance of CouchDBDao4Jobs */ public static CouchDBDao4Jobs getInstance() { if (me == null) { // ↖ no instance so far synchronized (CouchDBDao4Jobs.class) { if (me == null) { // ↖ still no instance so far // ↓ the one and only me me = new CouchDBDao4Jobs(); } } } return me; } /** * short for {@link #getInstance()} * * @return the one and only instance of CouchDBDao4Jobs */ public static CouchDBDao4Jobs me() { return getInstance(); } /** * return the current {@link JobDataProcessing} instance for the given * facility or <code>null</code> if nothing is defined * * @see couchdb <a href="http://localhost:5984/fam/_design/as/_list/newest_with_facility_key/all_job_data_processing?facilityKey=bus1" * >http://localhost:5984/fam/_design/as/_list/newest_with_facility_key * /all_job_data_processing?facilityKey=bus1</a> * @param useParent * if <code>true</code> and nothing is defined for given * facility, use parent facility and go on to root facility. only * if even the root facility has nothing defined return * <code>null</code>. */ @Override public JobDataProcessing getCurrentJobDataProcessing(Facility facility, boolean useParent) { QueryString queryString = QueryStringFactory.get("facilityKey", facility.getKey()); String uri = "_design/as/_list/newest_with_facility_key/all_job_data_processing"; try { return FamCouchDBDao.getInstance().getContentAsBean(uri, queryString, JobDataProcessing.class); } catch (JSONParseException e) { if (useParent && facility.hasParent()) { return this.getCurrentJobDataProcessing(facility.getParentFacility(), useParent); } else { return null; } } } /** * return the current {@link JobDataProcessing} instance for the given * facility or <code>null</code> if nothing is defined * * @see couchdb <a href="http://localhost:5984/fam/_design/as/_list/newest_with_facility_key/all_job_data_processing?facilityKey=bus1" * >http://localhost:5984/fam/_design/as/_list/newest_with_facility_key * /all_job_data_processing?facilityKey=bus1</a> * @param useParent * if <code>true</code> and nothing is defined for given * facility, use parent facility and go on to root facility. only * if even the root facility has nothing defined return * <code>null</code>. */ public JSONObject getCurrentJobDataProcessingAsJSONObject(Facility facility, List<Job> jobs, boolean useParent, boolean parseVelocity) { QueryString queryString = QueryStringFactory.get("facilityKey", facility.getKey()); String uri = "_design/as/_list/newest_with_facility_key/all_job_data_processing"; JSONObject result = null; try { String jsonResult = FamCouchDBDao.getInstance().getContentAsString(uri, queryString); result = new JSONObject(jsonResult); if (parseVelocity) { Facility facilityGot = FacilityConfigDao.facility(result.getString("facilityKey")); JobDataProcessingVelocityParser parser = new JobDataProcessingVelocityParser(facilityGot, jobs); parser.parse(result); } } catch (JSONParseException e) { } catch (JSONException e) { } if (result == null && useParent && facility.hasParent()) { return this.getCurrentJobDataProcessingAsJSONObject(facility.getParentFacility(), jobs, useParent, parseVelocity); } else { return result; } } /** {@inheritDoc} */ @Override public Job getJob(int jobId, int step) { Job result = null; QueryString queryString = QueryStringFactory.get("jobId", jobId + ""); queryString.put("step", step); String uri = "_design/as/_list/of_step_with_job_id/all_job"; try { result = FamCouchDBDao.getInstance().getContentAsBean(uri, queryString, Job.class); } catch (JSONParseException e) { // okay! just no Job found ... } return result; } /** {@inheritDoc} */ @Override public List<Job> getJobs(Booking booking) { return this.getJobs(booking.getId()); } /** {@inheritDoc} */ @Override public List<Job> getJobs(int jobid) { List<Job> result = new ArrayList<Job>(); int step = 0; do { Job tmp = this.getJob(jobid, step); if (tmp != null) { result.add(tmp); } step++; } while (step <= 4); return result; } /** {@inheritDoc} */ @Override public JobDataProcessing getJobDataProcessing(String id) { return FamCouchDBDao.getInstance().getContentAsBean(id, JobDataProcessing.class); } /** {@inheritDoc} */ @Override public JobDataProcessing getJobDataProcessing(Job job) { return this.getJobDataProcessing(job.getIdJobDataProcessing()); } /** {@inheritDoc} */ @Override public List<Job> getJobs(User user, boolean withFeedback) { List<Job> result = new ArrayList<Job>(); QueryString queryString = QueryStringFactory.get("username", user.getUsername() + ""); String uri = withFeedback ? "_design/as/_list/jobs_of_user_and_feedback/all_job" : "_design/as/_list/of_user/all_job"; uri += "?" + queryString.getAsQueryParams(false); Response response = FamCouchDBDao.response(uri); try { @SuppressWarnings({"unchecked", "rawtypes"}) List<Map> jobs = response.getContentAsList(); for (Map<?, ?> job : jobs) { result.add(FamCouchDBDao.getInstance().getContentAsBean(job.get("_id").toString(), Job.class)); } } catch (ClassCastException e) { FamLog.exception(e, 201205031134l); } finally { if (response != null) { response.destroy(); } } return result; } /** {@inheritDoc} */ @Override public boolean deleteJobs(User auth, User user, boolean withFeedback) { boolean result = FamAuth.hasRight(auth, FamAuth.DELETE_USERS_DATA, null); if (result) { List<Job> jobs = this.getJobs(user, withFeedback); if (jobs.size() > 0) { try { List<DocumentInfo> infos = FamCouchDBDao.admindatabase(auth).bulkDeleteDocuments(jobs, true); for (DocumentInfo info : infos) { if (info.getError() != null) { FamLog.error(info.getReason() + " / " + info.getId() + " / " + info.getRevision() + " / " + info.getError(), 201205041202l); result = false; } } } catch (NullPointerException e) { FamLog.exception("called by " + auth.getUsername() + " - ", e, 201205031337l); } catch (Exception e) { FamLog.exception(e, 201205031258l); } } } return result; } }