/*
* JBoss, Home of Professional Open Source
* Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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.jboss.arquillian.container.test.impl.enricher.resource;
import java.lang.annotation.Annotation;
import java.net.URI;
import java.net.URL;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext;
import org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData;
import org.jboss.arquillian.container.spi.client.protocol.metadata.Servlet;
import org.jboss.arquillian.container.test.api.TargetsContainer;
import org.jboss.arquillian.core.api.Instance;
import org.jboss.arquillian.core.api.annotation.Inject;
import org.jboss.arquillian.test.api.ArquillianResource;
/**
* URLResourceProvider
*
* @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a>
* @version $Revision: $
*/
public class URLResourceProvider extends OperatesOnDeploymentAwareProvider {
@Inject
private Instance<ProtocolMetaData> protocolMetadata;
@Override
public boolean canProvide(Class<?> type) {
return type.isAssignableFrom(URL.class);
}
@Override
public Object doLookup(ArquillianResource resource, Annotation... qualifiers) {
return locateURL(resource, locateTargetQualification(qualifiers));
}
private Object locateURL(ArquillianResource resource, TargetsContainer targets) {
ProtocolMetaData metaData = protocolMetadata.get();
if (metaData == null) {
return null;
}
if (metaData.hasContext(HTTPContext.class)) {
HTTPContext context = null;
if (targets != null) {
context = locateNamedHttpContext(metaData, targets.value());
} else {
context = metaData.getContexts(HTTPContext.class).iterator().next();
}
if (resource.value() != null && resource.value() != ArquillianResource.class) {
// TODO: we need to check for class. Not all containers have ServletClass available.
Servlet servlet = context.getServletByName(resource.value().getSimpleName());
if (servlet == null) {
servlet = context.getServletByName(resource.value().getName());
//throw new RuntimeException("No Servlet named " + resource.value().getSimpleName() + " found in metadata");
}
if (servlet == null) {
return null;
}
return toURL(servlet);
}
// TODO: evaluate, if all servlets are in the same context, and only one context exists, we can find the context
else if (allInSameContext(context.getServlets())) {
return toURL(context.getServlets().get(0));
} else {
return toURL(context);
}
}
return null;
}
private HTTPContext locateNamedHttpContext(ProtocolMetaData metaData, String value) {
for (HTTPContext context : metaData.getContexts(HTTPContext.class)) {
if (value.equals(context.getName())) {
return context;
}
}
throw new IllegalArgumentException(
"Could not find named context " + value + " in metadata. " +
"Please verify your @" + TargetsContainer.class.getName() + " definition");
}
private TargetsContainer locateTargetQualification(Annotation[] qualifiers) {
for (Annotation qualifier : qualifiers) {
if (TargetsContainer.class.isAssignableFrom(qualifier.annotationType())) {
return TargetsContainer.class.cast(qualifier);
}
}
return null;
}
private boolean allInSameContext(List<Servlet> servlets) {
Set<String> context = new HashSet<String>();
for (Servlet servlet : servlets) {
context.add(servlet.getContextRoot());
}
return context.size() == 1;
}
private URL toURL(Servlet servlet) {
try {
return servlet.getBaseURI().toURL();
} catch (Exception e) {
throw new RuntimeException("Could not convert Servlet to URL, " + servlet, e);
}
}
private URL toURL(HTTPContext context) {
try {
return new URI("http", null, context.getHost(), context.getPort(), null, null, null).toURL();
} catch (Exception e) {
throw new RuntimeException("Could not convert HTTPContext to URL, " + context, e);
}
}
}