001/**
002 * Copyright 2014 Tampere University of Technology, Pori Department
003 * 
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * 
008 *   http://www.apache.org/licenses/LICENSE-2.0
009 * 
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package service.tut.pori.contentanalysis.reference;
017
018import java.io.IOException;
019import java.io.InputStream;
020
021import org.apache.commons.io.IOUtils;
022import org.apache.log4j.Logger;
023
024import service.tut.pori.contentanalysis.PhotoParameters;
025import service.tut.pori.contentanalysis.PhotoParameters.AnalysisType;
026import service.tut.pori.contentanalysis.CAContentCore.ServiceType;
027import service.tut.pori.contentanalysis.Definitions;
028import service.tut.pori.contentanalysis.PhotoTaskDetails;
029import core.tut.pori.http.Response;
030import core.tut.pori.http.annotations.HTTPMethodParameter;
031import core.tut.pori.http.annotations.HTTPService;
032import core.tut.pori.http.annotations.HTTPServiceMethod;
033import core.tut.pori.http.parameters.DataGroups;
034import core.tut.pori.http.parameters.InputStreamParameter;
035import core.tut.pori.http.parameters.IntegerParameter;
036import core.tut.pori.http.parameters.Limits;
037import core.tut.pori.http.parameters.LongParameter;
038import core.tut.pori.http.parameters.StringParameter;
039import core.tut.pori.utils.XMLFormatter;
040
041/**
042 * 
043 * Reference implementation for Back-end APIs
044 *
045 */
046@HTTPService(name = service.tut.pori.contentanalysis.reference.Definitions.SERVICE_CA_REFERENCE_BACKEND)
047public class BackendService {
048  private static final Logger LOGGER = Logger.getLogger(BackendService.class);
049  private XMLFormatter _formatter = new XMLFormatter();
050  
051  /**
052   * The request is to be sent in the body of POST method. The Content-Type header MUST be set to "text/xml". The character set MUST be UTF-8. For example, "Content-Type: text/xml; charset=UTF-8".
053   * 
054   * <h2>Example Query:</h2>
055   *
056   * POST /rest/{@value service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_BACKEND}/{@value service.tut.pori.contentanalysis.Definitions#METHOD_ADD_TASK}<br>
057   * Content-Type: text/xml; charset=UTF-8<br><br>
058   *
059   * <b>[HTTP BODY STARTS]</b><br>
060   * 
061   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_TASK_DETAILS]" type="GET" query="" body_uri=""} <br>
062   * 
063   * <b>[HTTP BODY ENDS]</b><br>
064   *
065   * <h2>Example Result:</h2>
066   * 
067   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_BACKEND]" method="[service.tut.pori.contentanalysis.Definitions#METHOD_ADD_TASK]" type="POST" query="" body_uri="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]/[service.tut.pori.contentanalysis.Definitions#ELEMENT_TASK_DETAILS]"}
068   * 
069   * @param xml Only the workload data should be in the body. See {@link service.tut.pori.contentanalysis.PhotoTaskDetails}
070   */
071  @HTTPServiceMethod(name = Definitions.METHOD_ADD_TASK, acceptedMethods={core.tut.pori.http.Definitions.METHOD_POST})
072  public void addTask(@HTTPMethodParameter(name = InputStreamParameter.PARAMETER_DEFAULT_NAME, bodyParameter = true) InputStreamParameter xml) {
073    try {
074      String body = IOUtils.toString(xml.getValue()); // read the body
075      LOGGER.debug(body); // print to debug
076      try(InputStream input = IOUtils.toInputStream(body)){ // convert back to stream for unmarshal
077        CAReferenceCore.addTask(_formatter.toObject(input, PhotoTaskDetails.class, PhotoParameters.class));
078      }
079    } catch (IOException ex) {
080      LOGGER.error(ex, ex);
081    }
082  }
083  
084  /**
085   * This method can be used to query the current status of an analysis task from the back-end.
086   * 
087   * 
088   * <h2>Example Query:</h2>
089   *
090   * GET /rest/{@value service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_BACKEND}/{@value service.tut.pori.contentanalysis.Definitions#METHOD_QUERY_TASK_STATUS}?{@value service.tut.pori.contentanalysis.Definitions#PARAMETER_TASK_ID}=1<br>
091   *
092   * <h2>Example Result:</h2>
093   * 
094   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_BACKEND]" method="[service.tut.pori.contentanalysis.Definitions#METHOD_QUERY_TASK_STATUS]" type="GET" query="[service.tut.pori.contentanalysis.Definitions#PARAMETER_TASK_ID]=1" body_uri=""}
095   * 
096   * @param taskId
097   * @param dataGroups For supported data groups, see {@link service.tut.pori.contentanalysis.reference.ClientService#retrieveMediaObjects(core.tut.pori.http.parameters.AuthenticationParameter, DataGroups, Limits, core.tut.pori.http.parameters.IntegerParameter, core.tut.pori.http.parameters.StringParameter)}.
098   * @param limits paging limits
099   * @return See {@link service.tut.pori.contentanalysis.PhotoTaskResponse}
100   */
101  @HTTPServiceMethod(name = Definitions.METHOD_QUERY_TASK_STATUS, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET})
102  public Response queryTaskStatus(
103      @HTTPMethodParameter(name = Definitions.PARAMETER_TASK_ID) LongParameter taskId,
104      @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups,
105      @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits
106      )
107  {
108    return CAReferenceCore.queryTaskStatus(taskId.getValue(), dataGroups, limits);
109  }
110  
111  /**
112   * This method can be used to retrieve photos similar to the reference photo provided as a URL parameter.
113   * 
114   * <h2>Example Query:</h2>
115   *
116   * GET /rest/{@value service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_BACKEND}/{@value service.tut.pori.contentanalysis.Definitions#METHOD_SEARCH_SIMILAR_BY_CONTENT}?{@value service.tut.pori.contentanalysis.Definitions#PARAMETER_URL}=http%3A%2F%2Fexample.org%2Fphoto.jpg<br>
117   *
118   * <h2>Example Result:</h2>
119   * 
120   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_BACKEND]" method="[service.tut.pori.contentanalysis.Definitions#METHOD_SEARCH_SIMILAR_BY_CONTENT]" type="GET" query="[service.tut.pori.contentanalysis.Definitions#PARAMETER_URL]=http%3A%2F%2Fexample.org%2Fphoto.jpg" body_uri=""}
121   * 
122   * @param url publicly accessible URL with photo content
123   * @param analysisType optional list of analysis types to use for the search operation {@link service.tut.pori.contentanalysis.PhotoParameters.AnalysisType}
124   * @param dataGroups For supported data groups, see {@link service.tut.pori.contentanalysis.reference.ClientService#retrieveMediaObjects(core.tut.pori.http.parameters.AuthenticationParameter, DataGroups, Limits, core.tut.pori.http.parameters.IntegerParameter, core.tut.pori.http.parameters.StringParameter)}.
125   * @param limits paging limits
126   * @param serviceIds serviceIds If given, search is targeted only to the services with the listed ids. For supported service types, see {@link service.tut.pori.contentanalysis.CAContentCore.ServiceType}.
127   * @param userIdFilters If parameter is missing, search should be targeted only to publicly available photos.
128   * @return See {@link service.tut.pori.contentanalysis.PhotoList}
129   */
130  @HTTPServiceMethod(name = Definitions.METHOD_SEARCH_SIMILAR_BY_CONTENT, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET})
131  public Response similarPhotosByContent(
132      @HTTPMethodParameter(name = Definitions.PARAMETER_URL) StringParameter url,
133      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_ANALYSIS_TYPE, required = false) StringParameter analysisType,
134      @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups,
135      @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits,
136      @HTTPMethodParameter(name = Definitions.PARAMETER_SERVICE_ID, required = false) IntegerParameter serviceIds,
137      @HTTPMethodParameter(name = service.tut.pori.users.Definitions.PARAMETER_USER_ID, required = false) LongParameter userIdFilters
138      )
139  {
140    return CAReferenceCore.searchSimilarByContent(AnalysisType.fromAnalysisTypeString(analysisType.getValues()), url.getValue(), dataGroups, limits, ServiceType.fromIdArray(serviceIds.getValues()), userIdFilters.getValues());
141  }
142
143  /**
144   * This method is applicable for analysis back-ends that store the GUID and user information.
145   * 
146   * <h2>Example Query:</h2>
147   *
148   * GET /rest/{@value service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_BACKEND}/{@value service.tut.pori.contentanalysis.Definitions#METHOD_SEARCH_SIMILAR_BY_ID}?{@value service.tut.pori.contentanalysis.Definitions#PARAMETER_GUID}=1<br>
149   *
150   * <h2>Example Result:</h2>
151   * 
152   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_BACKEND]" method="[service.tut.pori.contentanalysis.Definitions#METHOD_SEARCH_SIMILAR_BY_ID]" type="GET" query="[service.tut.pori.contentanalysis.Definitions#PARAMETER_GUID]=1" body_uri=""}
153   * 
154   * @param guid video GUID
155   * @param analysisType optional list of analysis types to use for the search operation {@link service.tut.pori.contentanalysis.PhotoParameters.AnalysisType}
156   * @param dataGroups For supported data groups, see {@link service.tut.pori.contentanalysis.reference.ClientService#retrieveMediaObjects(core.tut.pori.http.parameters.AuthenticationParameter, DataGroups, Limits, core.tut.pori.http.parameters.IntegerParameter, core.tut.pori.http.parameters.StringParameter)}.
157   * @param limits paging limits
158   * @param serviceIds serviceIds If given, search is targeted only to the services with the listed ids. For supported service types, see {@link service.tut.pori.contentanalysis.CAContentCore.ServiceType}.
159   * @param userIdFilters If parameter is missing, search should be targeted only to publicly available photos.
160   * @return See {@link service.tut.pori.contentanalysis.PhotoList}
161   */
162  @HTTPServiceMethod(name = Definitions.METHOD_SEARCH_SIMILAR_BY_ID, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET})
163  public Response similarPhotosById(
164      @HTTPMethodParameter(name = Definitions.PARAMETER_GUID) StringParameter guid,
165      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_ANALYSIS_TYPE, required = false) StringParameter analysisType, 
166      @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups,
167      @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits,
168      @HTTPMethodParameter(name = Definitions.PARAMETER_SERVICE_ID, required = false) IntegerParameter serviceIds,
169      @HTTPMethodParameter(name = service.tut.pori.users.Definitions.PARAMETER_USER_ID, required = false) LongParameter userIdFilters
170      )
171  {
172    return CAReferenceCore.searchSimilarById(AnalysisType.fromAnalysisTypeString(analysisType.getValues()), guid.getValue(), dataGroups, limits, ServiceType.fromIdArray(serviceIds.getValues()), userIdFilters.getValues());
173  }
174}