Java tutorial
/** * Copyright 2008 The European Bioinformatics Institute, and others. * * 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.hupo.psi.mi.psicquic.ws; import org.apache.cxf.feature.Features; import org.apache.lucene.search.BooleanQuery; import org.hupo.psi.mi.psicquic.*; import org.hupo.psi.mi.psicquic.ws.config.PsicquicConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import psidev.psi.mi.search.SearchResult; import psidev.psi.mi.search.engine.SearchEngine; import psidev.psi.mi.search.engine.impl.BinaryInteractionSearchEngine; import psidev.psi.mi.tab.converter.tab2xml.Tab2Xml; import psidev.psi.mi.tab.model.BinaryInteraction; import psidev.psi.mi.tab.model.builder.MitabWriterUtils; import psidev.psi.mi.tab.model.builder.PsimiTabVersion; import psidev.psi.mi.xml.converter.impl254.EntrySetConverter; import psidev.psi.mi.xml.dao.inMemory.InMemoryDAOFactory; import psidev.psi.mi.xml254.jaxb.Attribute; import psidev.psi.mi.xml254.jaxb.AttributeList; import psidev.psi.mi.xml254.jaxb.Entry; import psidev.psi.mi.xml254.jaxb.EntrySet; import java.io.IOException; import java.util.*; /** * This web service is based on a PSIMITAB lucene's directory to search and return the results. * * @author Bruno Aranda (baranda@ebi.ac.uk) * @version $Id$ */ @Controller @Features(features = { "org.apache.cxf.transport.common.gzip.GZIPFeature" }) public class IndexBasedPsicquicService implements PsicquicService { private final Logger logger = LoggerFactory.getLogger(IndexBasedPsicquicService.class); private static final String RETURN_TYPE_XML25 = "psi-mi/xml25"; private static final String RETURN_TYPE_MITAB25 = "psi-mi/tab25"; private static final String RETURN_TYPE_COUNT = "count"; private static final String NEW_LINE = System.getProperty("line.separator"); public static final int BLOCKSIZE_MAX = 200; private static final String RETURN_TYPE_DEFAULT = RETURN_TYPE_MITAB25; public static final List<String> SUPPORTED_SOAP_RETURN_TYPES = Arrays.asList(RETURN_TYPE_XML25, RETURN_TYPE_MITAB25, RETURN_TYPE_COUNT); @Autowired private PsicquicConfig config; private Tab2Xml tab2Xml; public IndexBasedPsicquicService() { BooleanQuery.setMaxClauseCount(200 * 1000); } public QueryResponse getByInteractor(DbRef dbRef, RequestInfo requestInfo) throws NotSupportedMethodException, NotSupportedTypeException, PsicquicServiceException { String query = createQuery("identifiers", dbRef); return getByQuery(query, requestInfo); } public QueryResponse getByInteraction(DbRef dbRef, RequestInfo requestInfo) throws NotSupportedMethodException, NotSupportedTypeException, PsicquicServiceException { String query = createQuery("interaction_id", dbRef); return getByQuery(query, requestInfo); } public QueryResponse getByInteractorList(List<DbRef> dbRefs, RequestInfo requestInfo, String operand) throws NotSupportedMethodException, NotSupportedTypeException, PsicquicServiceException { String query = createQuery("identifiers", dbRefs, operand); return getByQuery(query, requestInfo); } public QueryResponse getByInteractionList(List<DbRef> dbRefs, RequestInfo requestInfo) throws PsicquicServiceException, NotSupportedMethodException, NotSupportedTypeException { String query = createQuery("interaction_id", dbRefs, "OR"); return getByQuery(query, requestInfo); } private String createQuery(String fieldName, DbRef dbRef) { return createQuery(fieldName, Collections.singleton(dbRef), null); } private String createQuery(String fieldName, Collection<DbRef> dbRefs, String operand) { StringBuilder sb = new StringBuilder(dbRefs.size() * 64); sb.append(fieldName).append(":("); for (Iterator<DbRef> dbRefIterator = dbRefs.iterator(); dbRefIterator.hasNext();) { DbRef dbRef = dbRefIterator.next(); sb.append(createQuery(dbRef)); if (dbRefIterator.hasNext()) { sb.append(" ").append(operand).append(" "); } } sb.append(")"); return sb.toString(); } private String createQuery(DbRef dbRef) { String db = dbRef.getDbAc(); String id = dbRef.getId(); return "(" + ((db == null || db.length() == 0) ? "\"" + id + "\"" : "\"" + db + "\" AND \"" + id + "\"") + ")"; } public QueryResponse getByQuery(String query, RequestInfo requestInfo) throws NotSupportedMethodException, NotSupportedTypeException, PsicquicServiceException { final int blockSize = Math.min(requestInfo.getBlockSize(), BLOCKSIZE_MAX); // apply any filter if (config.getQueryFilter() != null && !config.getQueryFilter().isEmpty()) { if ("*".equals(query) || query.trim().isEmpty()) { query = config.getQueryFilter(); } else { query = query + " " + config.getQueryFilter(); query = query.trim(); } } final String resultType = requestInfo.getResultType(); if (resultType != null && !getSupportedReturnTypes().contains(resultType)) { throw new NotSupportedTypeException("Not supported return type: " + resultType + " - Supported types are: " + getSupportedReturnTypes()); } // if (!new File(config.getIndexDirectory()).exists()) { // throw new PsicquicServiceException("Lucene directory does not exist: "+config.getIndexDirectory()); // } logger.debug("Searching: {} ({}/{})", new Object[] { query, requestInfo.getFirstResult(), blockSize }); SearchEngine searchEngine = null; try { searchEngine = new BinaryInteractionSearchEngine(config.getIndexDirectory()); } catch (IOException e) { e.printStackTrace(); if (searchEngine != null) { searchEngine.close(); } throw new PsicquicServiceException( "Problem creating SearchEngine using directory: " + config.getIndexDirectory(), e); } try { SearchResult searchResult = searchEngine.search(query, requestInfo.getFirstResult(), blockSize); // preparing the response QueryResponse queryResponse = new QueryResponse(); ResultInfo resultInfo = new ResultInfo(); resultInfo.setBlockSize(blockSize); resultInfo.setFirstResult(requestInfo.getFirstResult()); resultInfo.setTotalResults(searchResult.getTotalCount()); queryResponse.setResultInfo(resultInfo); ResultSet resultSet = createResultSet(query, searchResult, requestInfo); queryResponse.setResultSet(resultSet); searchEngine.close(); return queryResponse; } catch (Throwable e) { searchEngine.close(); throw new PsicquicServiceException("Cannot query PSICQUIC index ", e); } } public String getVersion() { return config.getVersion(); } public List<String> getSupportedReturnTypes() { return SUPPORTED_SOAP_RETURN_TYPES; } public List<String> getSupportedDbAcs() { return Collections.EMPTY_LIST; } public String getProperty(String propertyName) { return config.getProperties().get(propertyName); } public List<Property> getProperties() { List<Property> properties = new ArrayList<Property>(); for (Map.Entry<String, String> entry : config.getProperties().entrySet()) { Property prop = new Property(); prop.setKey(entry.getKey()); prop.setValue(entry.getValue()); properties.add(prop); } return properties; } protected ResultSet createResultSet(String query, SearchResult searchResult, RequestInfo requestInfo) throws PsicquicServiceException, NotSupportedTypeException { ResultSet resultSet = new ResultSet(); String resultType = (requestInfo.getResultType() != null) ? requestInfo.getResultType() : RETURN_TYPE_DEFAULT; if (RETURN_TYPE_MITAB25.equals(resultType)) { if (logger.isDebugEnabled()) logger.debug("Creating PSI-MI TAB"); String mitab = createMitabResults(searchResult); resultSet.setMitab(mitab); } else if (RETURN_TYPE_XML25.equals(resultType)) { if (logger.isDebugEnabled()) logger.debug("Creating PSI-MI XML"); EntrySet jEntrySet = createEntrySet(searchResult); resultSet.setEntrySet(jEntrySet); // add some annotations if (!jEntrySet.getEntries().isEmpty()) { AttributeList attrList = new AttributeList(); Entry entry = jEntrySet.getEntries().iterator().next(); Attribute attr = new Attribute(); attr.setValue("Data retrieved using the PSICQUIC service. Query: " + query); attrList.getAttributes().add(attr); Attribute attr2 = new Attribute(); attr2.setValue("Total results found: " + searchResult.getTotalCount()); attrList.getAttributes().add(attr2); // add warning if the batch size requested is higher than the maximum allowed if (requestInfo.getBlockSize() > BLOCKSIZE_MAX && BLOCKSIZE_MAX < searchResult.getTotalCount()) { Attribute attrWarning = new Attribute(); attrWarning.setValue("Warning: The requested block size (" + requestInfo.getBlockSize() + ") was higher than the maximum allowed (" + BLOCKSIZE_MAX + ") by PSICQUIC the service. " + BLOCKSIZE_MAX + " results were returned from a total found of " + searchResult.getTotalCount()); attrList.getAttributes().add(attrWarning); } entry.setAttributeList(attrList); } } else if (RETURN_TYPE_COUNT.equals(resultType)) { if (logger.isDebugEnabled()) logger.debug("Count query"); // nothing to be done here } else { throw new NotSupportedTypeException("Not supported return type: " + resultType + " - Supported types are: " + getSupportedReturnTypes()); } return resultSet; } protected String createMitabResults(SearchResult searchResult) { List<BinaryInteraction> binaryInteractions = searchResult.getData(); StringBuilder sb = new StringBuilder(binaryInteractions.size() * 512); for (BinaryInteraction binaryInteraction : binaryInteractions) { String binaryInteractionString = MitabWriterUtils.buildLine(binaryInteraction, PsimiTabVersion.v2_5); sb.append(binaryInteractionString); } return sb.toString(); } private EntrySet createEntrySet(SearchResult searchResult) throws PsicquicServiceException { if (searchResult.getData().isEmpty()) { return new EntrySet(); } this.tab2Xml = new Tab2Xml(); try { psidev.psi.mi.xml.model.EntrySet mEntrySet = tab2Xml.convert(searchResult.getData()); EntrySetConverter converter = new EntrySetConverter(); converter.setDAOFactory(new InMemoryDAOFactory()); return converter.toJaxb(mEntrySet); } catch (Exception e) { throw new PsicquicServiceException("Problem converting results to PSI-MI XML", e); } finally { // remove thread local values for this request tab2Xml.close(); } } }