/*
* ============================================================================
* GNU Lesser General Public License
* ============================================================================
*
* Beanlet - JSE Application Container.
* Copyright (C) 2006 Leon van Zantvoort
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Leon van Zantvoort
* 243 Acalanes Drive #11
* Sunnyvale, CA 94086
* USA
*
* zantvoort@users.sourceforge.net
* http://beanlet.org
*/
package org.beanlet.rest.jersey;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.core.spi.component.ComponentContext;
import com.sun.jersey.core.spi.component.ComponentScope;
import com.sun.jersey.core.spi.component.ioc.IoCComponentProvider;
import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory;
import com.sun.jersey.core.spi.component.ioc.IoCFullyManagedComponentProvider;
import com.sun.jersey.core.spi.component.ioc.IoCProxiedComponentProvider;
import com.sun.jersey.spi.container.WebApplication;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import org.beanlet.*;
import org.beanlet.rest.Restlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.util.Set;
public class JerseyRestContainer extends ServletContainer {
@Override
protected void initiate(ResourceConfig rc, WebApplication wa) {
class BeanletManagedComponentProvider implements IoCFullyManagedComponentProvider {
private final String beanletName;
public BeanletManagedComponentProvider(String beanletName) {
this.beanletName = beanletName;
}
// Never invoked.
public ComponentScope getScope() {
assert false;
return ComponentScope.Undefined;
}
// Is invoked every time server needs the class.
public Object getInstance() {
BeanletFactory<?> factory = BeanletApplicationContext.instance().getBeanletFactory(beanletName);
BeanletReference<?> reference = factory.create();
JerseyHelper.pushBeanletReference(reference);
return reference.getBeanlet();
}
};
class JersyManagedComponentProvider implements IoCProxiedComponentProvider {
private final String beanletName;
public JersyManagedComponentProvider(String beanletName) {
this.beanletName = beanletName;
}
// Never invoked.
public Object getInstance() {
assert false;
return null;
}
public Object proxy(Object o) {
assert o != null;
try {
JerseyHelper.setJerseyObject(beanletName, o);
return BeanletApplicationContext.instance().getBeanlet(beanletName);
} finally {
JerseyHelper.setJerseyObject(null, null);
}
}
}
wa.initiate(rc, new IoCComponentProviderFactory() {
public IoCComponentProvider getComponentProvider(Class<?> c) {
final IoCComponentProvider provider;
Set<String> beanletNames = BeanletApplicationContext.instance().getBeanletNamesForType(c);
if (beanletNames.isEmpty()) {
provider = null;
} else if (beanletNames.size() == 1) {
String beanletName = beanletNames.iterator().next();
BeanletFactory<?> factory = BeanletApplicationContext.instance().getBeanletFactory(beanletName);
Restlet restlet = factory.getBeanletMetaData().getAnnotation(Restlet.class);
if (restlet != null && restlet.createRestlet()) {
if (!factory.getBeanletMetaData().isVanilla() || factory.getBeanletMetaData().isStatic()) {
throw new BeanletValidationException(beanletName, "Restlet beanlets created by Rest runtime must be not non-static vanilla beanlets.");
}
provider = new JersyManagedComponentProvider(beanletName);
} else {
if (!factory.getBeanletMetaData().isVanilla()) {
throw new BeanletValidationException(beanletName, "Restlet beanlets created by Beanlet runtime must be vanilla beanlets.");
}
provider = new BeanletManagedComponentProvider(beanletName);
}
} else {
throw new BeanletApplicationException("Multiple beanlets exist for restlet type: " + c.getName() + ".");
}
return provider;
};
public IoCComponentProvider getComponentProvider(ComponentContext ctx, Class<?> c) {
return getComponentProvider(c);
}
});
}
@Override
public int service(URI baseUri, URI requestUri, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int size = JerseyHelper.getBeanletReferenceCount();
try {
return super.service(baseUri, requestUri, request, response);
} finally {
while (size > 0 && JerseyHelper.getBeanletReferenceCount() < size) {
BeanletReference<?> reference = JerseyHelper.popBeanletReference();
assert reference != null;
if (!reference.getBeanletMetaData().isStatic()) {
reference.invalidate();
}
}
}
}
}