001/**
002 * Copyright 2015 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.video.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.AnalysisType;
025import service.tut.pori.contentanalysis.CAContentCore.ServiceType;
026import service.tut.pori.contentanalysis.MediaObjectList;
027import service.tut.pori.contentanalysis.video.Definitions;
028import core.tut.pori.http.RedirectResponse;
029import core.tut.pori.http.Response;
030import core.tut.pori.http.annotations.HTTPAuthenticationParameter;
031import core.tut.pori.http.annotations.HTTPMethodParameter;
032import core.tut.pori.http.annotations.HTTPService;
033import core.tut.pori.http.annotations.HTTPServiceMethod;
034import core.tut.pori.http.parameters.AuthenticationParameter;
035import core.tut.pori.http.parameters.DataGroups;
036import core.tut.pori.http.parameters.InputStreamParameter;
037import core.tut.pori.http.parameters.IntegerParameter;
038import core.tut.pori.http.parameters.Limits;
039import core.tut.pori.http.parameters.LongParameter;
040import core.tut.pori.http.parameters.StringParameter;
041import core.tut.pori.utils.XMLFormatter;
042
043/**
044 * Reference implementation for client API methods.
045 * 
046 * <h1>Implementation Service path {@value service.tut.pori.contentanalysis.video.Definitions#SERVICE_VCA}</h1>
047 * 
048 * @see service.tut.pori.contentanalysis.video.VideoAnalysisService
049 *
050 */
051@HTTPService(name = service.tut.pori.contentanalysis.video.reference.Definitions.SERVICE_VCA_REFERENCE_CLIENT)
052public class ClientService {
053  private static final Logger LOGGER = Logger.getLogger(ClientService.class);
054  private XMLFormatter _formatter = new XMLFormatter();
055  
056  /**
057   * Redirects the client to the actual video location (i.e. redirects calls targeted to static front-end URLs to dynamic service specific URLs).
058   * The redirection method takes GUID and service id as a parameter. The redirection URLs are automatically generated for analysis tasks and user's search results by the front-end.
059   * 
060   * <h2>Example Query:</h2>
061   *
062   * GET /rest/{@value service.tut.pori.contentanalysis.video.reference.Definitions#SERVICE_VCA_REFERENCE_CLIENT}/{@value service.tut.pori.contentanalysis.Definitions#METHOD_REDIRECT}?{@value service.tut.pori.contentanalysis.Definitions#PARAMETER_GUID}=1&amp;{@value service.tut.pori.contentanalysis.Definitions#PARAMETER_SERVICE_ID}=1<br>
063   *
064   * <h2>Example Result:</h2>
065   * 
066   * REDIRECT / VIDEO CONTENT
067   * 
068   * @param authenticatedUser
069   * @param serviceId One of the supported service types, see {@link service.tut.pori.contentanalysis.CAContentCore.ServiceType}.
070   * @param guid video GUID
071   * @return redirection
072   */
073  @HTTPServiceMethod(name = service.tut.pori.contentanalysis.Definitions.METHOD_REDIRECT, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET})
074  public RedirectResponse r(
075      @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser,
076      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_SERVICE_ID) IntegerParameter serviceId,
077      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_GUID) StringParameter guid
078      )
079  {
080    return VideoReferenceCore.generateTargetUrl(authenticatedUser.getUserIdentity(), ServiceType.fromServiceId(serviceId.getValue()), guid.getValue());
081  }
082  
083  /**
084   * Search similar videos by giving a list of reference objects. All elements applicable to media objects are accepted as restrictive search terms. Note that missing elements (and element values) are assumed not to be included in the search, except "status" field, which is automatically assumed to be "USER_CONFIRMED" when no value is specified. The Media Object list 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".
085   * 
086   * <h2>Example Query:</h2>
087   * 
088   * POST /rest/{@value service.tut.pori.contentanalysis.video.reference.Definitions#SERVICE_VCA_REFERENCE_CLIENT}/{@value service.tut.pori.contentanalysis.video.Definitions#METHOD_SEARCH_SIMILAR_BY_OBJECT}<br>
089   * Content-Type: text/xml; charset=UTF-8<br><br>
090   *
091   * <b>[HTTP BODY STARTS]</b><br>
092   * 
093   * {@doc.restlet service="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]" method="[service.tut.pori.contentanalysis.Definitions#ELEMENT_MEDIA_OBJECTLIST]" type="GET" query="" body_uri=""} <br>
094   * 
095   * <b>[HTTP BODY ENDS]</b><br>
096   *
097   * <h2>Example Result:</h2>
098   * 
099   * {@doc.restlet service="[service.tut.pori.contentanalysis.video.reference.Definitions#SERVICE_VCA_REFERENCE_CLIENT]" method="[service.tut.pori.contentanalysis.video.Definitions#METHOD_SEARCH_SIMILAR_BY_OBJECT]" type="POST" query="" body_uri="[service.tut.pori.contentanalysis.reference.Definitions#SERVICE_CA_REFERENCE_EXAMPLE]/[service.tut.pori.contentanalysis.Definitions#ELEMENT_MEDIA_OBJECTLIST]"}
100   * 
101   * @param authenticatedUser
102   * @param dataGroups For supported data groups, see {@link service.tut.pori.contentanalysis.reference.ClientService#retrieveMediaObjects(AuthenticationParameter, DataGroups, Limits, IntegerParameter, StringParameter)}.
103   * @param limits paging limits
104   * @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}.
105   * @param userIdFilters If given, the search will return videos owned by the given user (provided that the currently logged in user has the required permissions).
106   * @param xml See {@link service.tut.pori.contentanalysis.MediaObjectList}
107   * @return See {@link service.tut.pori.contentanalysis.video.VideoList}
108   */
109  @HTTPServiceMethod(name = Definitions.METHOD_SEARCH_SIMILAR_BY_OBJECT, acceptedMethods={core.tut.pori.http.Definitions.METHOD_POST})
110  public Response similarVideosByObject(
111      @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser,
112      @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups,
113      @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits,
114      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_SERVICE_ID, required = false) IntegerParameter serviceIds,
115      @HTTPMethodParameter(name = service.tut.pori.users.Definitions.PARAMETER_USER_ID, required = false) LongParameter userIdFilters,
116      @HTTPMethodParameter(name = InputStreamParameter.PARAMETER_DEFAULT_NAME, bodyParameter = true) InputStreamParameter xml
117      )
118  {
119    try {
120      String body = IOUtils.toString(xml.getValue()); // read the body
121      LOGGER.debug(body); // print to debug
122      try(InputStream input = IOUtils.toInputStream(body)){ // convert back to stream for unmarshal
123        return VideoReferenceCore.similarVideosByObject(authenticatedUser.getUserIdentity(), _formatter.toObject(input, MediaObjectList.class), dataGroups, limits, ServiceType.fromIdArray(serviceIds.getValues()), userIdFilters.getValues());
124      }
125    } catch (IOException ex) {
126      LOGGER.error(ex, ex);
127      return null;
128    }
129  }
130  
131  /**
132   * This method can be used to retrieve the metadata of one or multiple videos. Any combination of parameters may be given for retrieving only the desired content (filtering the results). If you only want a list of media objects, this can be done with the method {@link service.tut.pori.contentanalysis.reference.ClientService#retrieveMediaObjects(AuthenticationParameter, DataGroups, Limits, IntegerParameter, StringParameter)}. If the user is not authenticated, access is only permitted to publicly available content.
133   *
134   * <h2>Example Query:</h2>
135   *
136   * GET /rest/{@value service.tut.pori.contentanalysis.video.reference.Definitions#SERVICE_VCA_REFERENCE_CLIENT}/{@value service.tut.pori.contentanalysis.video.Definitions#METHOD_RETRIEVE_VIDEO_METADATA}<br>
137   *
138   * <h2>Example Result:</h2>
139   * 
140   * {@doc.restlet service="[service.tut.pori.contentanalysis.video.reference.Definitions#SERVICE_VCA_REFERENCE_CLIENT]" method="[service.tut.pori.contentanalysis.video.Definitions#METHOD_RETRIEVE_VIDEO_METADATA]" type="GET" query="" body_uri=""}
141   * 
142   * @param authenticatedUser
143   * @param guid One or more GUIDs for retrieval.
144   * @param dataGroups For supported data groups, see {@link service.tut.pori.contentanalysis.reference.ClientService#retrieveMediaObjects(AuthenticationParameter, DataGroups, Limits, IntegerParameter, StringParameter)}.
145   * @param limits paging limits
146   * @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}. 
147   * @param userIds If given, the search will return videos owned by the given user (provided that the currently logged in user has the required permissions).
148   * @return See {@link service.tut.pori.contentanalysis.video.VideoList}
149   */
150  @HTTPServiceMethod(name = Definitions.METHOD_RETRIEVE_VIDEO_METADATA, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET})
151  public Response getVideos(
152      @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser,
153      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_GUID, required=false) StringParameter guid,
154      @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups,
155      @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits,
156      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_SERVICE_ID, required = false) IntegerParameter serviceIds,
157      @HTTPMethodParameter(name = service.tut.pori.users.Definitions.PARAMETER_USER_ID, required = false) LongParameter userIds
158      )
159  {
160    return VideoReferenceCore.getVideos(authenticatedUser.getUserIdentity(), guid.getValues(), dataGroups, limits, ServiceType.fromIdArray(serviceIds.getValues()), userIds.getValues());
161  }
162  
163  /**
164   * Search for videos which are similar to the video designated by the given GUID parameter. Non-authenticated users only have access to publicly available content.
165   * 
166   * <h2>Example Query:</h2>
167   *
168   * GET /rest/{@value service.tut.pori.contentanalysis.video.reference.Definitions#SERVICE_VCA_REFERENCE_CLIENT}/{@value service.tut.pori.contentanalysis.video.Definitions#METHOD_SEARCH_SIMILAR_BY_ID}?{@value service.tut.pori.contentanalysis.Definitions#PARAMETER_GUID}=1<br>
169   *
170   * <h2>Example Result:</h2>
171   * 
172   * {@doc.restlet service="[service.tut.pori.contentanalysis.video.reference.Definitions#SERVICE_VCA_REFERENCE_CLIENT]" method="[service.tut.pori.contentanalysis.video.Definitions#METHOD_SEARCH_SIMILAR_BY_ID]" type="GET" query="[service.tut.pori.contentanalysis.Definitions#PARAMETER_GUID]=1" body_uri=""}
173   * 
174   * @param authenticatedUser
175   * @param guid photo GUID
176   * @param analysisType optional list of analysis types to use for the search operation {@link service.tut.pori.contentanalysis.PhotoParameters.AnalysisType}
177   * @param dataGroups For supported data groups, see {@link service.tut.pori.contentanalysis.reference.ClientService#retrieveMediaObjects(AuthenticationParameter, DataGroups, Limits, IntegerParameter, StringParameter)}
178   * @param limits paging limits
179   * @param 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}.
180   * @param userIdFilters If given, the search will return photos owned by the given user (provided that the currently logged in user has the required permissions).
181   * @return See {@link service.tut.pori.contentanalysis.video.VideoList}
182   */
183  @HTTPServiceMethod(name = Definitions.METHOD_SEARCH_SIMILAR_BY_ID, acceptedMethods={core.tut.pori.http.Definitions.METHOD_GET})
184  public Response searchSimilarById(
185      @HTTPAuthenticationParameter(required = false) AuthenticationParameter authenticatedUser,
186      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_GUID) StringParameter guid, 
187      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_ANALYSIS_TYPE, required = false) StringParameter analysisType, 
188      @HTTPMethodParameter(name = DataGroups.PARAMETER_DEFAULT_NAME, required = false) DataGroups dataGroups,
189      @HTTPMethodParameter(name = Limits.PARAMETER_DEFAULT_NAME, required = false) Limits limits,
190      @HTTPMethodParameter(name = service.tut.pori.contentanalysis.Definitions.PARAMETER_SERVICE_ID, required = false) IntegerParameter serviceIds,
191      @HTTPMethodParameter(name = service.tut.pori.users.Definitions.PARAMETER_USER_ID, required = false) LongParameter userIdFilters
192      ) 
193  {
194    return VideoReferenceCore.searchSimilarById(authenticatedUser.getUserIdentity(), AnalysisType.fromAnalysisTypeString(analysisType.getValues()), guid.getValue(), dataGroups, limits, ServiceType.fromIdArray(serviceIds.getValues()), userIdFilters.getValues());
195  }
196}