/**
*
* Copyright
* 2009-2015 Jayway Products AB
* 2016-2017 Föreningen Sambruk
*
* Licensed under AGPL, Version 3.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.gnu.org/licenses/agpl.txt
*
* 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 se.streamsource.streamflow.server.plugin.restlet;
import org.json.JSONException;
import org.qi4j.api.common.Optional;
import org.qi4j.api.common.QualifiedName;
import org.qi4j.api.injection.scope.Service;
import org.qi4j.api.injection.scope.Structure;
import org.qi4j.api.property.Property;
import org.qi4j.api.property.StateHolder;
import org.qi4j.api.value.ValueBuilder;
import org.qi4j.api.value.ValueComposite;
import org.qi4j.spi.Qi4jSPI;
import org.qi4j.spi.property.PropertyType;
import org.qi4j.spi.structure.ModuleSPI;
import org.qi4j.spi.value.ValueDescriptor;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.data.CharacterSet;
import org.restlet.data.Form;
import org.restlet.data.Language;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Parameter;
import org.restlet.data.Status;
import org.restlet.representation.InputRepresentation;
import org.restlet.representation.StringRepresentation;
import se.streamsource.streamflow.server.plugin.contact.ContactList;
import se.streamsource.streamflow.server.plugin.contact.ContactLookup;
import se.streamsource.streamflow.server.plugin.contact.ContactValue;
/**
* Delegate Restlet calls to the ContactLookup service.
*/
public class ContactLookupRestlet
extends Restlet
{
@Optional
@Service
ContactLookup contactLookup;
@Structure
private Qi4jSPI spi;
@Structure
private ModuleSPI module;
@Override
public void handle( Request request, Response response )
{
super.handle( request, response );
try
{
if (contactLookup == null)
{
response.setStatus( Status.CLIENT_ERROR_NOT_FOUND );
return;
}
if (request.getMethod().equals( Method.GET ))
{
if (request.getResourceRef().getQuery() == null || request.getResourceRef().getQuery().isEmpty())
{
response.setEntity( new InputRepresentation( getClass().getResourceAsStream( "contactform.html" ) ) );
response.setStatus( Status.SUCCESS_OK );
} else
{
// Parse request
ContactValue contactTemplate;
// check if the call comes from REST API
Form queryAsForm = request.getResourceRef().getQueryAsForm();
Parameter template = queryAsForm.getFirst( "template" );
if( template == null )
{
contactTemplate = (ContactValue) getValueFromForm( ContactValue.class, queryAsForm );
} else
{
contactTemplate = module.valueBuilderFactory().newValueFromJSON( ContactValue.class, template.getValue() );
}
// Call plugin
ContactList lookups = contactLookup.lookup( contactTemplate );
// Send response
String json = lookups.toJSON();
StringRepresentation result = new StringRepresentation( json, MediaType.APPLICATION_JSON, Language.DEFAULT, CharacterSet.UTF_8 );
response.setStatus( Status.SUCCESS_OK );
response.setEntity( result );
}
} else
{
response.setStatus( Status.CLIENT_ERROR_METHOD_NOT_ALLOWED );
}
} finally
{
request.release();
}
}
private ValueComposite getValueFromForm( Class<? extends ValueComposite> valueType, final Form asForm )
{
ValueBuilder<? extends ValueComposite> builder = module.valueBuilderFactory().newValueBuilder(valueType);
final ValueDescriptor descriptor = spi.getValueDescriptor( builder.prototype() );
builder.withState( new StateHolder()
{
public <T> Property<T> getProperty( QualifiedName name )
{
return null;
}
public <T> Property<T> getProperty( java.lang.reflect.Method propertyMethod )
{
return null;
}
public <ThrowableType extends Throwable> void visitProperties( StateVisitor<ThrowableType> visitor )
throws ThrowableType
{
for (PropertyType propertyType : descriptor.valueType().types())
{
Parameter param = asForm.getFirst( propertyType.qualifiedName().name() );
if (param != null)
{
String value = param.getValue();
if (value == null)
value = "";
try
{
Object valueObject = propertyType.type().fromQueryParameter( value, module );
visitor.visitProperty( propertyType.qualifiedName(), valueObject );
} catch (JSONException e)
{
throw new IllegalArgumentException( "Query parameter has invalid JSON format", e );
}
}
}
}
} );
return builder.newInstance();
}
}