/* * * YAQP - Yet Another QSAR Project: * Machine Learning algorithms designed for the prediction of toxicological * features of chemical compounds become available on the Web. Yaqp is developed * under OpenTox (http://opentox.org) which is an FP7-funded EU research project. * This project was developed at the Automatic Control Lab in the Chemical Engineering * School of the National Technical University of Athens. Please read README for more * information. * * Copyright (C) 2009-2010 Pantelis Sopasakis & Charalampos Chomenides * * 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/>. * * Contact: * Pantelis Sopasakis * chvng@mail.ntua.gr * Address: Iroon Politechniou St. 9, Zografou, Athens Greece * tel. +30 210 7723236 */ package org.opentox.www.rest.resources; import java.io.File; import org.opentox.config.Configuration; import org.opentox.config.ServerFolders; import org.opentox.core.exceptions.Cause; import org.opentox.core.exceptions.YaqpException; import org.opentox.core.processors.Pipeline; import org.opentox.db.exceptions.DbException; import org.opentox.db.handlers.ReaderHandler; import org.opentox.db.handlers.UpdateHandler; import org.opentox.db.util.Page; import org.opentox.io.processors.OutputProcessor; import org.opentox.io.processors.Publisher; import org.opentox.ontology.components.ComponentList; import org.opentox.ontology.components.QSARModel; import org.opentox.ontology.components.User; import org.opentox.ontology.exceptions.ImproperEntityException; import org.opentox.qsar.processors.predictors.SimplePredictor; import org.opentox.util.logging.YaqpLogger; import org.opentox.util.logging.levels.Fatal; import org.opentox.www.rest.components.URITemplate; import org.opentox.www.rest.components.YaqpForm; import org.opentox.www.rest.components.YaqpResource; import org.opentox.www.rest.services.PredictionService; import org.restlet.data.MediaType; import org.restlet.data.Reference; import org.restlet.data.Status; import org.restlet.representation.Representation; import org.restlet.representation.Variant; import org.restlet.resource.ResourceException; /** * * @author Pantelis Sopasakis * @author Charalampos Chomenides */ public class ModelResource extends YaqpResource { public static final URITemplate template = URITemplate.primarySubtemplateOf(ModelsResource.template, "modelId"); private String model_id; private static final String modelNotFoundMessage = "The model you are looking for was not found on the server. Check out " + Configuration.BASE_URI + ModelsResource.template.toString() + " for a complete list of the " + "available models." + NEWLINE; /** * Initialized the resource * @throws ResourceException * In case the resource cannot be initialized. */ @Override protected void doInit() throws ResourceException { super.doInit(); initialize( MediaType.APPLICATION_RDF_XML, MediaType.APPLICATION_RDF_TURTLE, MediaType.APPLICATION_PDF, MediaType.TEXT_URI_LIST); model_id = Reference.decode(getRequest().getAttributes().get(template.getPrimaryKey()).toString()); } // TODO: Better exception handling and status codes. @Override @SuppressWarnings({"unchecked"}) protected Representation get(Variant variant) throws ResourceException { QSARModel prototype = new QSARModel(); try { prototype.setId(Integer.parseInt(model_id)); } catch (NumberFormatException ex) { getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); return sendMessage(modelNotFoundMessage); } try { ComponentList listOfModels = ReaderHandler.search(prototype, new Page(), false); if (listOfModels.size() == 0) { toggleNotFound(); return sendMessage(modelNotFoundMessage); } QSARModel mod = (QSARModel) listOfModels.getFirst(); final Publisher publisher = new Publisher(variant.getMediaType()); final OutputProcessor representer = new OutputProcessor(); final Pipeline pipe = new Pipeline(publisher, representer); toggleSuccess(); return (Representation) pipe.process(mod); } catch (YaqpException ex) { YaqpLogger.LOG.log(new Fatal(getClass(), "Excpetion caught : {" + ex + "}")); toggleServerError(); return sendMessage(_DEAD_DB_); } } // TODO: Better exception handling and status codes. @Override protected Representation post(Representation entity, Variant variant) throws ResourceException { /* * First try to locate the model and see if it exists... */ QSARModel prototype = new QSARModel(); try { prototype.setId(Integer.parseInt(model_id)); } catch (NumberFormatException ex) { getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); return sendMessage(modelNotFoundMessage); } ComponentList listOfModels; try { listOfModels = ReaderHandler.search(prototype, new Page(), false); if (listOfModels.size() == 0) { getResponse().setStatus(Status.CLIENT_ERROR_NOT_FOUND); return sendMessage(modelNotFoundMessage); } } catch (YaqpException ex) { YaqpLogger.LOG.log(new Fatal(getClass(), "Excpetion caught : {" + ex + "}")); toggleServerError(); return sendMessage(_DEAD_DB_); } /* * Apply the prediction service to calculate the predictions and * POST the results to a dataset service. */ PredictionService service; try { service = new PredictionService(new YaqpForm(entity), model_id, new User(), SimplePredictor.class, variant.getMediaType()); toggleSuccess(); return service.call(); } catch (final YaqpException ex) { toggleBadRequest(); if (ex.getCode() == Cause.XIO5052) { toggleRemoteError(); } return sendMessage(ex.toString() + NEWLINE); } catch (Exception ex) { YaqpLogger.LOG.log(new Fatal(getClass(), "Excpetion caught : {" + ex + "}")); return sendMessage(_500_); } } @Override protected Representation delete(final Variant variant) throws ResourceException { QSARModel modelToBeDeleted = new QSARModel(); try{ modelToBeDeleted.setId(Integer.parseInt(this.model_id)); }catch (final NumberFormatException nfe){ toggleNotFound(); return sendMessage("The model you attempted to delete was not found on the server" + NEWLINE); } try { ComponentList list = ReaderHandler.search(modelToBeDeleted, new Page(), false); if (list.size()==0) throw new DbException(); QSARModel model = (QSARModel) list.getFirst(); String code = model.getCode(); System.out.println(code); UpdateHandler.delete(modelToBeDeleted); new File(ServerFolders.models_weka+"/"+code).renameTo(new File(ServerFolders.Trash+"/"+code)); new File(ServerFolders.models_pmml+"/"+code).renameTo(new File(ServerFolders.Trash+"/"+code+".pmml")); } catch (final DbException ex) { toggleNotFound(); return sendMessage("The model "+Configuration.BASE_URI+"/model/"+this.model_id+" was not found on the server"+NEWLINE); } catch (final ImproperEntityException ex) { /* do nothing */ } toggleSuccess(); return sendMessage("The model "+Configuration.BASE_URI+"/model/"+this.model_id+" was successfully deleted. " + "If you need to recover it, send a message to the service administrators providing the URI of the model you need to " + "recover. However, once deleted, there is no guarrantee that it will be possible to recover it successfully. Note that the" + "deleted model will be automatically deleted after 1 month!"+NEWLINE); } }