/**
* Copyright Intellectual Reserve, Inc.
*
* 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.familysearch.api.client;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.client.urlconnection.URLConnectionClientHandler;
import org.familysearch.api.client.rt.FamilySearchPlatformJsonProvider;
import org.familysearch.platform.Error;
import org.familysearch.platform.FamilySearchPlatform;
import org.familysearch.platform.Tag;
import org.familysearch.platform.artifacts.ArtifactMetadata;
import org.familysearch.platform.ct.*;
import org.familysearch.platform.discussions.Discussion;
import org.familysearch.platform.ordinances.Ordinance;
import org.familysearch.platform.places.FeedbackInfo;
import org.familysearch.platform.users.User;
import org.gedcomx.common.ExtensibleData;
import org.gedcomx.rs.client.*;
import org.gedcomx.rs.client.util.HttpWarning;
import org.gedcomx.rt.GedcomxConstants;
import org.gedcomx.rt.json.GedcomxAtomJsonProvider;
import javax.ws.rs.HttpMethod;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.util.List;
/**
* @author Ryan Heaton
*/
public class FamilySearchStateFactory extends StateFactory {
protected DiscussionsState newDiscussionsState(ClientRequest request, ClientResponse response, String accessToken) {
return new DiscussionsState(request, response, accessToken, this);
}
protected DiscussionState newDiscussionState(ClientRequest request, ClientResponse response, String accessToken) {
return new DiscussionState(request, response, accessToken, this);
}
protected UserState newUserState(ClientRequest request, ClientResponse response, String accessToken) {
return new UserState(request, response, accessToken, this);
}
protected UserHistoryState newUserHistoryState(ClientRequest request, ClientResponse response, String accessToken) {
return new UserHistoryState(request, response, accessToken, this);
}
protected PersonMatchResultsState newPersonMatchResultsState(ClientRequest request, ClientResponse response, String accessToken) {
return new PersonMatchResultsState(request, response, accessToken, this);
}
@Override
protected SourceDescriptionsState newSourceDescriptionsState(ClientRequest request, ClientResponse response, String accessToken) {
return super.newSourceDescriptionsState(request, response, accessToken);
}
/**
* Create a new places state with the given URI
*
* @param discoveryUri the discovery URI for places
* @return a new places state created with with the given URI
*/
public FamilySearchPlaces newPlacesState(URI discoveryUri) {
return newPlacesState(discoveryUri, loadDefaultClient());
}
/**
* Create a new places state with the given URI
*
* @param discoveryUri the discovery URI for places
* @param client the client that will use the new places state
* @return a new places state created with with the given URI
*/
public FamilySearchPlaces newPlacesState(URI discoveryUri, Client client) {
return newPlacesState(discoveryUri, client, HttpMethod.GET);
}
/**
* Create a new places state with the given URI
*
* @param discoveryUri the discovery URI for places
* @param client the client that will use the new places state
* @param method the HTTP method to call
* @return a new places state created with with the given URI
*/
public FamilySearchPlaces newPlacesState(URI discoveryUri, Client client, String method) {
ClientRequest request = ClientRequest.create().accept(GedcomxConstants.GEDCOMX_JSON_MEDIA_TYPE).build(discoveryUri, method);
return newPlacesState(request, client.handle(request), null);
}
protected FamilySearchPlaces newPlacesState(ClientRequest request, ClientResponse response, String accessToken) {
return new FamilySearchPlaces(request, response, accessToken, this);
}
@Override
protected FamilySearchCollectionState newCollectionState(ClientRequest request, ClientResponse response, String accessToken) {
return new FamilySearchCollectionState(request, response, accessToken, this);
}
@Override
protected FamilySearchSourceDescriptionState newSourceDescriptionState(ClientRequest request, ClientResponse response, String accessToken) {
return new FamilySearchSourceDescriptionState(request, response, accessToken, this);
}
@Override
protected FamilySearchPersonState newPersonState(ClientRequest request, ClientResponse response, String accessToken) {
return new FamilySearchPersonState(request, response, accessToken, this);
}
protected PersonNonMatchesState newPersonNonMatchesState(ClientRequest request, ClientResponse response, String accessToken) {
return new PersonNonMatchesState(request, response, accessToken, this);
}
protected FamilySearchPlaceState newPlaceState(ClientRequest request, ClientResponse response, String accessToken) {
return new FamilySearchPlaceState(request, response, accessToken, this);
}
@Override
protected PlaceDescriptionState newPlaceDescriptionState(ClientRequest request, ClientResponse response, String accessToken) {
return new FamilySearchPlaceDescriptionState(request, response, accessToken, this);
}
@Override
protected RecordsState newRecordsState(ClientRequest request, ClientResponse response, String accessToken) {
return super.newRecordsState(request, response, accessToken);
}
public FamilySearchReservationsState newFamilySearchReservationsState() {
return new FamilySearchReservationsState(true);
}
public FamilySearchReservationsState newFamilySearchReservationsState(boolean production) {
return new FamilySearchReservationsState(production);
}
public FamilySearchReservationsState newFamilySearchReservationsState(URI discoveryUri) {
return new FamilySearchReservationsState(discoveryUri);
}
protected ChangeHistoryState newChangeHistoryState(ClientRequest request, ClientResponse response, String accessToken) {
return new ChangeHistoryState(request, response, accessToken, this);
}
protected OrdinanceReservationsState newOrdinanceReservationsState(ClientRequest request, ClientResponse response, String accessToken) {
return new OrdinanceReservationsState(request, response, accessToken, this);
}
protected PersonOrdinancesState newPersonOrdinancesState(ClientRequest request, ClientResponse response, String accessToken) {
return new PersonOrdinancesState(request, response, accessToken, this);
}
protected OrdinanceStatusState newOrdinanceStatusState(ClientRequest request, ClientResponse response, String accessToken) {
return new OrdinanceStatusState(request, response, accessToken, this);
}
protected TempleCardPrintSetState newTempleCardPrintSetState(ClientRequest request, ClientResponse clientResponse, String accessToken) {
return new TempleCardPrintSetState(request, clientResponse, accessToken, this);
}
protected PlaceSearchResultsState newPlaceSearchResultsState(ClientRequest request, ClientResponse response, String accessToken) {
return new PlaceSearchResultsState(request, response, accessToken, this);
}
protected PlaceGroupState newPlaceGroupState(ClientRequest request, ClientResponse response, String accessToken) {
return new PlaceGroupState(request, response, accessToken, this);
}
protected NameSearchResultsState newNameSearchResultsState(ClientRequest request, ClientResponse response, String accessToken) {
return new NameSearchResultsState(request, response, accessToken, this);
}
@Override
public Client loadDefaultClient() {
DefaultClientConfig config = new DefaultClientConfig();
Class<?>[] extensionClasses = new Class[]{ FamilySearchPlatform.class, ArtifactMetadata.class, ChangeInfo.class,
ChildAndParentsRelationship.class, Discussion.class, DiscussionReference.class,
Error.class, FeedbackInfo.class, MatchInfo.class, SearchInfo.class, Merge.class, MergeAnalysis.class, MergeConflict.class,
Tag.class, User.class, Ordinance.class };
config.getSingletons().add( new FamilySearchPlatformJsonProvider(extensionClasses) );
config.getSingletons().add( new GedcomxAtomJsonProvider(extensionClasses) );
config.getSingletons().add( new JacksonJsonProvider() );
Client client = new Client(new URLConnectionClientHandler(), config);
//how to add an experiment:
//client.addFilter(new ExperimentsFilter("experiment-name", "experiment-name"));
if (Boolean.valueOf(System.getProperty(ENABLE_JERSEY_LOGGING_ENV_NAME))) { // handles null
client.addFilter(new com.sun.jersey.api.client.filter.LoggingFilter());
}
return client;
}
@Override
protected String buildErrorMessage(GedcomxApplicationState state) {
StringBuilder builder = new StringBuilder("Unsuccessful ").append(state.getRequest().getMethod()).append(" to ").append(state.getUri()).append(" (").append(state.getResponse().getStatus()).append(")");
if (state.getEntity() instanceof ExtensibleData) {
org.familysearch.platform.Error errorInfo = ((ExtensibleData) state.getEntity()).findExtensionOfType(Error.class);
if (errorInfo != null) {
if (errorInfo.getMessage() != null) {
builder.append(": ").append(errorInfo.getMessage());
}
if (errorInfo.getStacktrace() != null) {
BufferedReader reader = new BufferedReader(new StringReader(errorInfo.getStacktrace()));
try {
String line = reader.readLine();
while (line != null) {
builder.append("\n ").append(line);
line = reader.readLine();
}
}
catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
}
List<HttpWarning> warnings = state.getWarnings();
if (warnings != null && warnings.size() > 0) {
for (HttpWarning warning : warnings) {
builder.append("\nWarning: ").append(warning.getMessage());
}
}
return builder.toString();
}
}