Method from org.apache.geronimo.web25.deployment.AbstractWebModuleBuilder Detail: |
protected void addGBeanDependencies(EARContext earContext,
GBeanData webModuleData) {
Configuration earConfiguration = earContext.getConfiguration();
addDependencies(earContext.findGBeanDatas(earConfiguration, MANAGED_CONNECTION_FACTORY_PATTERN), webModuleData);
addDependencies(earContext.findGBeanDatas(earConfiguration, ADMIN_OBJECT_PATTERN), webModuleData);
addDependencies(earContext.findGBeanDatas(earConfiguration, STATELESS_SESSION_BEAN_PATTERN), webModuleData);
addDependencies(earContext.findGBeanDatas(earConfiguration, STATEFUL_SESSION_BEAN_PATTERN), webModuleData);
addDependencies(earContext.findGBeanDatas(earConfiguration, ENTITY_BEAN_PATTERN), webModuleData);
}
|
protected void basicInitContext(EARContext earContext,
Module module,
XmlObject gerWebApp,
boolean hasSecurityRealmName) throws DeploymentException {
//complete manifest classpath
EARContext moduleContext = module.getEarContext();
ClassPathList manifestcp = (ClassPathList) moduleContext.getGeneralData().get(ClassPathList.class);
ModuleList moduleLocations = (ModuleList) module.getRootEarContext().getGeneralData().get(ModuleList.class);
URI baseUri = URI.create(module.getTargetPath());
URI resolutionUri = invertURI(baseUri);
earContext.getCompleteManifestClassPath(module.getModuleFile(), baseUri, resolutionUri, manifestcp, moduleLocations);
WebAppType webApp = (WebAppType) module.getSpecDD();
if ((webApp.getSecurityConstraintArray().length > 0 || webApp.getSecurityRoleArray().length > 0)) {
if (!hasSecurityRealmName) {
throw new DeploymentException("web.xml for web app " + module.getName() + " includes security elements but Geronimo deployment plan is not provided or does not contain < security-realm-name > element necessary to configure security accordingly.");
}
}
if (hasSecurityRealmName) {
earContext.setHasSecurity(true);
}
//TODO think about how to provide a default security realm name
XmlObject[] securityElements = XmlBeansUtil.selectSubstitutionGroupElements(SECURITY_QNAME, gerWebApp);
if (securityElements.length > 0 && !hasSecurityRealmName) {
throw new DeploymentException("You have supplied a security configuration for web app " + module.getName() + " but no security-realm-name to allow login");
}
getNamingBuilders().buildEnvironment(webApp, module.getVendorDD(), module.getEnvironment());
//this is silly
getNamingBuilders().initContext(webApp, gerWebApp, module);
Map servletNameToPathMap = buildServletNameToPathMap((WebAppType) module.getSpecDD(), ((WebModule) module).getContextRoot());
Map sharedContext = module.getSharedContext();
for (Object aWebServiceBuilder : webServiceBuilder) {
WebServiceBuilder serviceBuilder = (WebServiceBuilder) aWebServiceBuilder;
serviceBuilder.findWebServices(module, false, servletNameToPathMap, module.getEnvironment(), sharedContext);
}
serviceBuilders.build(gerWebApp, earContext, module.getEarContext());
}
|
protected Map<String, String> buildServletNameToPathMap(WebAppType webApp,
String contextRoot) {
if (contextRoot == null) {
contextRoot = "";
} else if (!contextRoot.startsWith("/")) {
contextRoot = "/" + contextRoot;
}
Map< String, String > map = new HashMap< String, String >();
ServletMappingType[] servletMappings = webApp.getServletMappingArray();
for (ServletMappingType servletMapping : servletMappings) {
String servletName = servletMapping.getServletName().getStringValue().trim();
UrlPatternType[] urlPatterns = servletMapping.getUrlPatternArray();
for (int i = 0; urlPatterns != null && (i < urlPatterns.length); i++) {
map.put(servletName, contextRoot + urlPatterns[i].getStringValue().trim());
}
}
return map;
}
Some servlets will have multiple url patterns. However, webservice servlets
will only have one, which is what this method is intended for. |
protected ComponentPermissions buildSpecSecurityConfig(WebAppType webApp) {
SpecSecurityBuilder builder = new SpecSecurityBuilder();
return builder.buildSpecSecurityConfig(webApp);
}
|
protected static void check(WebAppType webApp) throws DeploymentException {
checkURLPattern(webApp);
checkMultiplicities(webApp);
}
|
protected static void checkString(String pattern) throws DeploymentException {
//j2ee_1_4.xsd explicitly requires preserving all whitespace. Do not trim.
if (pattern.indexOf(0x0D) >= 0) throw new DeploymentException("< url-pattern > must not contain CR(#xD)");
if (pattern.indexOf(0x0A) >= 0) throw new DeploymentException("< url-pattern > must not contain LF(#xA)");
}
|
protected void configureBasicWebModuleAttributes(WebAppType webApp,
XmlObject vendorPlan,
EARContext moduleContext,
EARContext earContext,
WebModule webModule,
GBeanData webModuleData) throws DeploymentException {
Map< NamingBuilder.Key, Object > buildingContext = new HashMap< NamingBuilder.Key, Object >();
buildingContext.put(NamingBuilder.GBEAN_NAME_KEY, moduleContext.getModuleName());
if (!webApp.getMetadataComplete()) {
// Create a classfinder and populate it for the naming builder(s). The absence of a
// classFinder in the module will convey whether metadata-complete is set (or not)
webModule.setClassFinder(createWebAppClassFinder(webApp, webModule));
SecurityAnnotationHelper.processAnnotations(webApp, webModule.getClassFinder());
}
//N.B. we use the ear context which has all the gbeans we could possibly be looking up from this ear.
//nope, persistence units can be in the war.
//This means that you cannot use the default environment of the web builder to add configs that will be searched.
getNamingBuilders().buildNaming(webApp, vendorPlan, webModule, buildingContext);
Map compContext = NamingBuilder.JNDI_KEY.get(buildingContext);
Holder holder = NamingBuilder.INJECTION_KEY.get(buildingContext);
webModule.getSharedContext().put(WebModule.WEB_APP_DATA, webModuleData);
webModule.getSharedContext().put(NamingBuilder.JNDI_KEY, compContext);
webModule.getSharedContext().put(NamingBuilder.INJECTION_KEY, holder);
if (moduleContext.getServerName() != null) {
webModuleData.setReferencePattern("J2EEServer", moduleContext.getServerName());
}
if (!webModule.isStandAlone()) {
webModuleData.setReferencePattern("J2EEApplication", earContext.getModuleName());
}
webModuleData.setAttribute("holder", holder);
//Add dependencies on managed connection factories and ejbs in this app
//This is overkill, but allows for people not using java:comp context (even though we don't support it)
//and sidesteps the problem of circular references between ejbs.
if (earContext != moduleContext) {
addGBeanDependencies(earContext, webModuleData);
}
webModuleData.setAttribute("componentContext", compContext);
webModuleData.setReferencePattern("TransactionManager", moduleContext.getTransactionManagerName());
webModuleData.setReferencePattern("TrackedConnectionAssociator", moduleContext.getConnectionTrackerName());
}
|
protected void configureLocalJaspicProvider(AuthenticationWrapper authType,
String contextPath,
Module module,
GBeanData securityFactoryData) throws DeploymentException, GBeanAlreadyExistsException {
EARContext moduleContext = module.getEarContext();
GBeanData authConfigProviderData = null;
AbstractName providerName = moduleContext.getNaming().createChildName(module.getModuleName(), "authConfigProvider", GBeanInfoBuilder.DEFAULT_J2EE_TYPE);
try {
if (authType.isSetConfigProvider()) {
authConfigProviderData = new GBeanData(providerName, AuthConfigProviderGBean.class);
final XmlCursor xmlCursor = authType.getConfigProvider().newCursor();
try {
XMLStreamReader reader = new InternWrapper(xmlCursor.newXMLStreamReader());
ConfigProviderType configProviderType = JaspiXmlUtil.loadConfigProvider(reader);
StringWriter out = new StringWriter();
JaspiXmlUtil.writeConfigProvider(configProviderType, out);
authConfigProviderData.setAttribute("config", out.toString());
} finally {
xmlCursor.dispose();
}
} else if (authType.isSetServerAuthConfig()) {
authConfigProviderData = new GBeanData(providerName, ServerAuthConfigGBean.class);
final XmlCursor xmlCursor = authType.getServerAuthConfig().newCursor();
try {
XMLStreamReader reader = new InternWrapper(xmlCursor.newXMLStreamReader());
ServerAuthConfigType serverAuthConfigType = JaspiXmlUtil.loadServerAuthConfig(reader);
StringWriter out = new StringWriter();
JaspiXmlUtil.writeServerAuthConfig(serverAuthConfigType, out);
authConfigProviderData.setAttribute("config", out.toString());
} finally {
xmlCursor.dispose();
}
} else if (authType.isSetServerAuthContext()) {
authConfigProviderData = new GBeanData(providerName, ServerAuthContextGBean.class);
final XmlCursor xmlCursor = authType.getServerAuthContext().newCursor();
try {
XMLStreamReader reader = new InternWrapper(xmlCursor.newXMLStreamReader());
ServerAuthContextType serverAuthContextType = JaspiXmlUtil.loadServerAuthContext(reader);
StringWriter out = new StringWriter();
JaspiXmlUtil.writeServerAuthContext(serverAuthContextType, out);
authConfigProviderData.setAttribute("config", out.toString());
} finally {
xmlCursor.dispose();
}
} else if (authType.isSetServerAuthModule()) {
authConfigProviderData = new GBeanData(providerName, ServerAuthModuleGBean.class);
final XmlCursor xmlCursor = authType.getServerAuthModule().newCursor();
try {
XMLStreamReader reader = new InternWrapper(xmlCursor.newXMLStreamReader());
AuthModuleType< ServerAuthModule > authModuleType = JaspiXmlUtil.loadServerAuthModule(reader);
StringWriter out = new StringWriter();
JaspiXmlUtil.writeServerAuthModule(authModuleType, out);
authConfigProviderData.setAttribute("config", out.toString());
authConfigProviderData.setAttribute("messageLayer", "Http");
authConfigProviderData.setAttribute("appContext", contextPath);
//TODO ??
authConfigProviderData.setAttribute("authenticationID", contextPath);
} finally {
xmlCursor.dispose();
}
}
} catch (ParserConfigurationException e) {
throw new DeploymentException("Could not read auth config", e);
} catch (IOException e) {
throw new DeploymentException("Could not read auth config", e);
} catch (SAXException e) {
throw new DeploymentException("Could not read auth config", e);
} catch (JAXBException e) {
throw new DeploymentException("Could not read auth config", e);
} catch (XMLStreamException e) {
throw new DeploymentException("Could not read auth config", e);
}
if (authConfigProviderData != null) {
moduleContext.addGBean(authConfigProviderData);
securityFactoryData.addDependency(authConfigProviderData.getAbstractName());
}
}
|
protected WebAppDocument convertToServletSchema(XmlObject xmlObject) throws XmlException {
String schemaLocationURL = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd";
String version = "2.5";
XmlCursor cursor = xmlObject.newCursor();
try {
cursor.toStartDoc();
cursor.toFirstChild();
if ("http://java.sun.com/xml/ns/j2ee".equals(cursor.getName().getNamespaceURI())) {
SchemaConversionUtils.convertSchemaVersion(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, schemaLocationURL, version);
XmlObject result = xmlObject.changeType(WebAppDocument.type);
XmlBeansUtil.validateDD(result);
return (WebAppDocument) result;
}
if ("http://java.sun.com/xml/ns/javaee".equals(cursor.getName().getNamespaceURI())) {
SchemaConversionUtils.convertSchemaVersion(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, schemaLocationURL, version);
XmlObject result = xmlObject.changeType(WebAppDocument.type);
XmlBeansUtil.validateDD(result);
return (WebAppDocument) result;
}
//otherwise assume DTD
XmlDocumentProperties xmlDocumentProperties = cursor.documentProperties();
String publicId = xmlDocumentProperties.getDoctypePublicId();
boolean is22 = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN".equals(publicId);
if ("-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN".equals(publicId) ||
is22) {
XmlCursor moveable = xmlObject.newCursor();
try {
moveable.toStartDoc();
moveable.toFirstChild();
SchemaConversionUtils.convertToSchema(cursor, SchemaConversionUtils.JAVAEE_NAMESPACE, schemaLocationURL, version);
cursor.toStartDoc();
cursor.toChild(SchemaConversionUtils.JAVAEE_NAMESPACE, "web-app");
cursor.toFirstChild();
SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
SchemaConversionUtils.convertToJNDIEnvironmentRefsGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
cursor.push();
if (cursor.toNextSibling(TAGLIB)) {
cursor.toPrevSibling();
moveable.toCursor(cursor);
cursor.beginElement("jsp-config", SchemaConversionUtils.JAVAEE_NAMESPACE);
while (moveable.toNextSibling(TAGLIB)) {
moveable.moveXml(cursor);
}
}
cursor.pop();
do {
String name = cursor.getName().getLocalPart();
if ("filter".equals(name) || "servlet".equals(name) || "context-param".equals(name)) {
cursor.push();
cursor.toFirstChild();
SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
while (cursor.toNextSibling(SchemaConversionUtils.JAVAEE_NAMESPACE, "init-param")) {
cursor.push();
cursor.toFirstChild();
SchemaConversionUtils.convertToDescriptionGroup(SchemaConversionUtils.JAVAEE_NAMESPACE, cursor, moveable);
cursor.pop();
}
cursor.pop();
cursor.push();
if (cursor.toChild(SchemaConversionUtils.JAVAEE_NAMESPACE, "jsp-file")) {
String jspFile = cursor.getTextValue();
if (!jspFile.startsWith("/")){
if (is22) {
cursor.setTextValue("/" + jspFile);
} else {
throw new XmlException("jsp-file does not start with / and this is not a 2.2 web app: " + jspFile);
}
}
}
cursor.pop();
}
} while (cursor.toNextSibling());
} finally {
moveable.dispose();
}
}
} finally {
cursor.dispose();
}
XmlObject result = xmlObject.changeType(WebAppDocument.type);
if (result != null) {
XmlBeansUtil.validateDD(result);
return (WebAppDocument) result;
}
XmlBeansUtil.validateDD(xmlObject);
return (WebAppDocument) xmlObject;
}
|
public Module createModule(File plan,
JarFile moduleFile,
Naming naming,
ModuleIDBuilder idBuilder) throws DeploymentException {
return createModule(plan, moduleFile, ".", null, true, null, null, naming, idBuilder);
}
|
public Module createModule(Object plan,
JarFile moduleFile,
String targetPath,
URL specDDUrl,
Environment environment,
Object moduleContextInfo,
AbstractName earName,
Naming naming,
ModuleIDBuilder idBuilder) throws DeploymentException {
return createModule(plan, moduleFile, targetPath, specDDUrl, false, (String) moduleContextInfo, earName, naming, idBuilder);
}
|
abstract protected Module createModule(Object plan,
JarFile moduleFile,
String targetPath,
URL specDDUrl,
boolean standAlone,
String contextRoot,
AbstractName earName,
Naming naming,
ModuleIDBuilder idBuilder) throws DeploymentException
|
protected ClassFinder createWebAppClassFinder(WebAppType webApp,
WebModule webModule) throws DeploymentException {
// Get the classloader from the module's EARContext
ClassLoader classLoader = webModule.getEarContext().getClassLoader();
return createWebAppClassFinder(webApp, classLoader);
}
|
public static ClassFinder createWebAppClassFinder(WebAppType webApp,
ClassLoader classLoader) throws DeploymentException {
//------------------------------------------------------------------------------------
// Find the list of classes from the web.xml we want to search for annotations in
//------------------------------------------------------------------------------------
List< Class > classes = new ArrayList< Class >();
// Get all the servlets from the deployment descriptor
ServletType[] servlets = webApp.getServletArray();
for (ServletType servlet : servlets) {
FullyQualifiedClassType cls = servlet.getServletClass();
if (cls != null) { // Don't try this for JSPs
Class< ? > clas;
try {
clas = classLoader.loadClass(cls.getStringValue());
} catch (ClassNotFoundException e) {
throw new DeploymentException("AbstractWebModuleBuilder: Could not load servlet class: " + cls.getStringValue(), e);
}
addClass(classes, clas);
}
}
// Get all the listeners from the deployment descriptor
ListenerType[] listeners = webApp.getListenerArray();
for (ListenerType listener : listeners) {
FullyQualifiedClassType cls = listener.getListenerClass();
Class< ? > clas;
try {
clas = classLoader.loadClass(cls.getStringValue());
} catch (ClassNotFoundException e) {
throw new DeploymentException("AbstractWebModuleBuilder: Could not load listener class: " + cls.getStringValue(), e);
}
addClass(classes, clas);
}
// Get all the filters from the deployment descriptor
FilterType[] filters = webApp.getFilterArray();
for (FilterType filter : filters) {
FullyQualifiedClassType cls = filter.getFilterClass();
Class< ? > clas;
try {
clas = classLoader.loadClass(cls.getStringValue());
} catch (ClassNotFoundException e) {
throw new DeploymentException("AbstractWebModuleBuilder: Could not load filter class: " + cls.getStringValue(), e);
}
addClass(classes, clas);
}
// see https://issues.apache.org/jira/browse/GERONIMO-3421 .
// if the user has botched her classloader config (perhaps by
// not including a jar that her app needs) then ClassFinder
// will throw NoClassDefFoundError. we want to indicate that
// it's the user's error and provide a little context to help
// her fix it.
try {
return new ClassFinder(classes);
} catch (NoClassDefFoundError e) {
throw new DeploymentException("Classloader for " + webApp.getId() + "can't find " + e.getMessage(), e);
}
}
|
protected String determineDefaultContextRoot(WebAppType webApp,
boolean isStandAlone,
JarFile moduleFile,
String targetPath) {
if (webApp != null && webApp.getId() != null) {
return webApp.getId();
}
if (isStandAlone) {
// default configId is based on the moduleFile name
return "/" + trimPath(new File(moduleFile.getName()).getName());
}
// default configId is based on the module uri from the application.xml
return trimPath(targetPath);
}
|
public NamingBuilder getNamingBuilders() {
return namingBuilders;
}
|
public void installModule(JarFile earFile,
EARContext earContext,
Module module,
Collection configurationStores,
ConfigurationStore targetConfigurationStore,
Collection repositories) throws DeploymentException {
EARContext moduleContext;
if (module.isStandAlone()) {
moduleContext = earContext;
} else {
Environment environment = module.getEnvironment();
Artifact earConfigId = earContext.getConfigID();
Artifact configId = new Artifact(earConfigId.getGroupId(), earConfigId.getArtifactId() + "_" + module.getTargetPath(), earConfigId.getVersion(), "car");
environment.setConfigId(configId);
environment.addDependency(earConfigId, ImportType.ALL);
File configurationDir = new File(earContext.getBaseDir(), module.getTargetPath());
configurationDir.mkdirs();
// construct the web app deployment context... this is the same class used by the ear context
try {
File inPlaceConfigurationDir = null;
if (null != earContext.getInPlaceConfigurationDir()) {
inPlaceConfigurationDir = new File(earContext.getInPlaceConfigurationDir(), module.getTargetPath());
}
moduleContext = new EARContext(configurationDir,
inPlaceConfigurationDir,
environment,
ConfigurationModuleType.WAR,
module.getModuleName(),
earContext);
} catch (DeploymentException e) {
cleanupConfigurationDir(configurationDir);
throw e;
}
}
module.setEarContext(moduleContext);
module.setRootEarContext(earContext);
try {
ClassPathList manifestcp = new ClassPathList();
// add the warfile's content to the configuration
JarFile warFile = module.getModuleFile();
Enumeration< JarEntry > entries = warFile.entries();
List< ZipEntry > libs = new ArrayList< ZipEntry >();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
URI targetPath = new URI(null, entry.getName(), null);
if (entry.getName().equals("WEB-INF/web.xml")) {
moduleContext.addFile(targetPath, module.getOriginalSpecDD());
} else if (entry.getName().startsWith("WEB-INF/lib") && entry.getName().endsWith(".jar")) {
// keep a collection of all libs in the war
// libs must be installed after WEB-INF/classes which must be installed after this copy phase
libs.add(entry);
} else {
moduleContext.addFile(targetPath, warFile, entry);
}
}
// always add WEB-INF/classes to the classpath regardless of whether
// any classes exist. This must be searched BEFORE the WEB-INF/lib jar files,
// per the servlet specifications.
moduleContext.getConfiguration().addToClassPath("WEB-INF/classes/");
manifestcp.add("WEB-INF/classes/");
// install the libs
for (ZipEntry entry : libs) {
URI targetPath = new URI(null, entry.getName(), null);
moduleContext.addInclude(targetPath, warFile, entry);
manifestcp.add(entry.getName());
}
// add the manifest classpath entries declared in the war to the class loader
// we have to explicitly add these since we are unpacking the web module
// and the url class loader will not pick up a manifest from an unpacked dir
moduleContext.addManifestClassPath(warFile, RELATIVE_MODULE_BASE_URI);
moduleContext.getGeneralData().put(ClassPathList.class, manifestcp);
} catch (IOException e) {
throw new DeploymentException("Problem deploying war", e);
} catch (URISyntaxException e) {
throw new DeploymentException("Could not construct URI for location of war entry", e);
} finally {
if (!module.isStandAlone()) {
try {
moduleContext.flush();
} catch (IOException e) {
throw new DeploymentException("Problem closing war context", e);
}
}
}
for (ModuleBuilderExtension mbe: moduleBuilderExtensions) {
mbe.installModule(earFile, earContext, module, configurationStores, targetConfigurationStore, repositories);
}
}
|
static URI invertURI(URI baseUri) {
URI resolutionUri = URI.create(".");
for (URI test = baseUri; !test.equals(RELATIVE_MODULE_BASE_URI); test = test.resolve(RELATIVE_MODULE_BASE_URI)) {
resolutionUri = resolutionUri.resolve(RELATIVE_MODULE_BASE_URI);
}
return resolutionUri;
}
|