net.officefloor.web.response.ObjectResponseManagedObjectSource Maven / Gradle / Ivy
/*
* OfficeFloor - http://www.officefloor.net
* Copyright (C) 2005-2018 Daniel Sagenschneider
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package net.officefloor.web.response;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import net.officefloor.compile.impl.util.CompileUtil;
import net.officefloor.frame.api.build.None;
import net.officefloor.frame.api.escalate.Escalation;
import net.officefloor.frame.api.managedobject.CoordinatingManagedObject;
import net.officefloor.frame.api.managedobject.ManagedObject;
import net.officefloor.frame.api.managedobject.ObjectRegistry;
import net.officefloor.frame.api.managedobject.ProcessAwareContext;
import net.officefloor.frame.api.managedobject.ProcessAwareManagedObject;
import net.officefloor.frame.api.managedobject.source.ManagedObjectSource;
import net.officefloor.frame.api.managedobject.source.impl.AbstractManagedObjectSource;
import net.officefloor.frame.api.source.PrivateSource;
import net.officefloor.server.http.HttpEscalationContext;
import net.officefloor.server.http.HttpEscalationHandler;
import net.officefloor.server.http.HttpException;
import net.officefloor.server.http.HttpHeaderName;
import net.officefloor.server.http.HttpHeaderValue;
import net.officefloor.server.http.HttpStatus;
import net.officefloor.server.http.ServerHttpConnection;
import net.officefloor.server.http.WritableHttpHeader;
import net.officefloor.web.ObjectResponse;
import net.officefloor.web.accept.AcceptNegotiator;
import net.officefloor.web.accept.AcceptNegotiatorBuilderImpl;
import net.officefloor.web.build.AcceptNegotiatorBuilder;
import net.officefloor.web.build.HttpObjectResponder;
import net.officefloor.web.build.HttpObjectResponderFactory;
import net.officefloor.web.build.NoAcceptHandlersException;
/**
* {@link ManagedObjectSource} for the {@link ObjectResponse}.
*
* @author Daniel Sagenschneider
*/
@PrivateSource
public class ObjectResponseManagedObjectSource
extends AbstractManagedObjectSource
implements HttpEscalationHandler {
/**
* Obtains the default {@link HttpObjectResponderFactory}.
*/
@FunctionalInterface
public static interface DefaultHttpObjectResponder {
/**
* Obtains the default {@link HttpObjectResponderFactory}.
*
* @return Default {@link HttpObjectResponderFactory}.
* @throws Exception If fails to obtain the default
* {@link HttpObjectResponderFactory}.
*/
HttpObjectResponderFactory getDefaultHttpObjectResponderFactory() throws Exception;
}
/**
* Dependency keys.
*/
public static enum ObjectResponseDependencies {
SERVER_HTTP_CONNECTION
}
/**
* {@link List} of {@link HttpObjectResponderFactory} instances.
*/
private final List objectResponderFactoriesList;
/**
* {@link DefaultHttpObjectResponder}.
*/
private final DefaultHttpObjectResponder defaultHttpObjectResponder;
/**
* {@link AcceptNegotiator} for the {@link Object} {@link ContentTypeCache}.
*/
private AcceptNegotiator objectNegotiator;
/**
* {@link AcceptNegotiator} for the {@link Escalation} {@link ContentTypeCache}.
*/
private AcceptNegotiator escalationNegotiator;
/**
* {@link WritableHttpHeader} instances when not acceptable type requested.
*/
private WritableHttpHeader[] notAcceptableHeaders;
/**
* Instantiate.
*
* @param objectResponderFactories {@link List} of
* {@link HttpObjectResponderFactory}
* instances.
* @param defaultHttpObjectResponder {@link DefaultHttpObjectResponder}.
*/
public ObjectResponseManagedObjectSource(List objectResponderFactories,
DefaultHttpObjectResponder defaultHttpObjectResponder) {
this.objectResponderFactoriesList = objectResponderFactories;
this.defaultHttpObjectResponder = defaultHttpObjectResponder;
}
/*
* ==================== ManagedObjectSource ======================
*/
@Override
protected void loadSpecification(SpecificationContext context) {
}
@Override
protected void loadMetaData(MetaDataContext context) throws Exception {
// Load the meta-data
context.setObjectClass(ObjectResponse.class);
context.setManagedObjectClass(ObjectResponseManagedObject.class);
context.addDependency(ObjectResponseDependencies.SERVER_HTTP_CONNECTION, ServerHttpConnection.class);
// Create the not acceptable headers
StringBuilder accept = new StringBuilder();
boolean isFirst = true;
// Create the negotiators
AcceptNegotiatorBuilder objectBuilder = new AcceptNegotiatorBuilderImpl<>();
AcceptNegotiatorBuilder escalationBuilder = new AcceptNegotiatorBuilderImpl<>();
NEXT_FACTORY: for (HttpObjectResponderFactory factory : this.objectResponderFactoriesList) {
String contentType = factory.getContentType();
if (CompileUtil.isBlank(contentType)) {
continue NEXT_FACTORY;
}
// Add content-type for negotiator
objectBuilder.addHandler(contentType, new ContentTypeCache(factory));
escalationBuilder.addHandler(contentType, new ContentTypeCache(factory));
// Include in accept header response
if (!isFirst) {
accept.append(", ");
}
isFirst = false;
accept.append(contentType);
}
if (isFirst) {
// Determine if provide default responder
HttpObjectResponderFactory defaultFactory = this.defaultHttpObjectResponder
.getDefaultHttpObjectResponderFactory();
if (defaultFactory != null) {
// Provide default
String contentType = defaultFactory.getContentType();
if (!CompileUtil.isBlank(contentType)) {
// Add content-type for negotiator
objectBuilder.addHandler(contentType, new ContentTypeCache(defaultFactory));
escalationBuilder.addHandler(contentType, new ContentTypeCache(defaultFactory));
// Only the one, so is the accept type
accept.append(contentType);
}
}
}
try {
this.objectNegotiator = objectBuilder.build();
this.escalationNegotiator = escalationBuilder.build();
} catch (NoAcceptHandlersException ex) {
throw new Exception(
"Must have at least one " + HttpObjectResponderFactory.class.getSimpleName() + " configured");
}
// Create the not acceptable headers
this.notAcceptableHeaders = new WritableHttpHeader[] {
new WritableHttpHeader(new HttpHeaderName("accept"), new HttpHeaderValue(accept.toString())) };
}
@Override
protected ManagedObject getManagedObject() throws Throwable {
return new ObjectResponseManagedObject
© 2015 - 2025 Weber Informatics LLC | Privacy Policy