/* * $HeadURL$ * $Id$ * * Copyright (c) 2006-2010 by Public Library of Science * http://plos.org * http://ambraproject.org * * 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 org.ambraproject.service.journal; import org.ambraproject.models.Article; import org.apache.commons.configuration.Configuration; import org.apache.struts2.ServletActionContext; import org.hibernate.Criteria; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Restrictions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Required; import org.springframework.transaction.annotation.Transactional; import org.ambraproject.models.Journal; import org.ambraproject.service.hibernate.HibernateServiceImpl; import org.ambraproject.web.VirtualJournalContext; import java.util.HashSet; import java.util.List; import java.util.Set; /** * A collection of methods for manipulating and querying journal information * * @author Joe Osowski */ public class JournalServiceImpl extends HibernateServiceImpl implements JournalService { private static final Logger log = LoggerFactory.getLogger(JournalServiceImpl.class); private Configuration configuration; /** * Create a new journal-service instance. One and only one of these should be created for every * session-factory instance, and this must be done before the first session instance is created. */ public JournalServiceImpl() { } /** * Get the specified journal. * * @param journalKey the journal's key * @return the journal, or null if not found */ @Override @Transactional(readOnly = true) @SuppressWarnings("unchecked") public Journal getJournal(final String journalKey) { List<Journal> journals = (List<Journal>) hibernateTemplate.findByCriteria( DetachedCriteria.forClass(Journal.class) .add(Restrictions.eq("journalKey", journalKey)) .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) ); if(journals.size() == 0) return null; return journals.get(0); } /** * Get the Journal from its <strong>eIssn</strong>. * * @param eIssn the journal's eIssn value. * @return the journal, or null if not found */ @Transactional(readOnly = true) @SuppressWarnings("unchecked") public synchronized Journal getJournalByEissn(final String eIssn) { List<Journal> journals = (List<Journal>) hibernateTemplate.findByCriteria( DetachedCriteria.forClass(Journal.class) .add(Restrictions.eq("eIssn", eIssn)),0, 1); if(journals.size() == 0) return null; return journals.get(0); } /** * Get the set of all the known journals. * * @return all the journals, or the empty set if there are none */ @Transactional(readOnly = true) public Set<Journal> getAllJournals() { Set<Journal> res = new HashSet<Journal>(); for (String jName : getAllJournalNames()) res.add(getJournal(jName)); res.remove(null); // in case something got deleted from under us return res; } /** * Get the names of all the known journals. * * @return the list of names; may be empty if there are no known journals */ @Transactional(readOnly = true) @SuppressWarnings("unchecked") public Set<String> getAllJournalNames() { return new HashSet<String>(configuration.getList("ambra.virtualJournals.journals")); } /** * This method makes services dependent on servlet context. * Use getCurrentJournal() method in Action class instead. * . * Get the name of the current journal. * * @return the name of the current journal, or null if there is no current journal */ @Deprecated public String getCurrentJournalName() { VirtualJournalContext vjc = (VirtualJournalContext) ServletActionContext.getRequest() .getAttribute(VirtualJournalContext.PUB_VIRTUALJOURNAL_CONTEXT); return (vjc == null) ? null : vjc.getJournal(); } @Transactional(readOnly = true) @Override @SuppressWarnings("unchecked") public Set<Journal> getJournalsForObject(final String doi) { Set<Journal> journals = new HashSet<Journal>(2); //probably only going to be one journal //Is there a more efficient way to do this without using inline SQL? List<Article> articles = (List<Article>) hibernateTemplate.findByCriteria( DetachedCriteria.forClass(Article.class) .add(Restrictions.eq("doi", doi))); if(articles.size() > 0) { journals.addAll(articles.get(0).getJournals()); } return journals; // // this is for cross published objects // journals.addAll(hibernateTemplate.executeFind(new HibernateCallback() { // @Override // public Object doInHibernate(Session session) throws HibernateException, SQLException { // return session.createSQLQuery( // "SELECT {j.*} FROM journal j" + // " join articlePublishedJournals apj on apj.journalID = j.journalID" + // " join article a on a.articleID = apj.articleID" + // " WHERE a.doi = :doi") // .addEntity("j", Journal.class) // .setParameter("doi", doi) // .list(); // } // })); // // return journals; } /** * Get the list of journalNames which carry the given object (e.g. article). * * @param doi the info:<oid> uri of the object * @return the list of journal Name which carry this object; will be empty if this object * doesn't belong to any journal */ @Transactional(readOnly = true) @SuppressWarnings("unchecked") public Set<String> getJournalKeysForObject(final String doi) { Set<String> journalNames = new HashSet(); Set<Journal> journals = getJournalsForObject(doi); for(Journal j : journals) { journalNames.add(j.getJournalKey()); } return journalNames; } /** * Setter method for configuration. Injected through Spring. * * @param configuration Ambra configuration */ @Required public void setConfiguration(Configuration configuration) { this.configuration = configuration; } }