/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.tuscany.sca.wicket; import javax.servlet.ServletContext; import org.apache.wicket.Application; import org.apache.wicket.IClusterable; import org.apache.wicket.MetaDataKey; import org.apache.wicket.Session; import org.apache.wicket.application.IComponentInstantiationListener; import org.apache.wicket.injection.ComponentInjector; import org.apache.wicket.injection.web.InjectorHolder; import org.apache.wicket.model.Model; import org.apache.wicket.protocol.http.WebApplication; /** * {@link IComponentInstantiationListener} that injects component properties annotated with {@link * SpringBean} annotations. * * To install in yourapplication.init() call * addComponentInstantiationListener(new SpringComponentInjector(this)); Non-wicket * components such as {@link Session}, {@link Model}, and any other pojo can be injected by calling * InjectorHolder.getInjector().inject(this) in their constructor. * * Based on code from Apache Wicket by Igor Vaynberg and Justin Lee */ public class TuscanyComponentInjector extends ComponentInjector { /** * Metadata key used to store application context holder in application's metadata */ private static MetaDataKey CONTEXT_KEY = new MetaDataKey() { private static final long serialVersionUID = 1L; }; /** * Constructor used when spring application context is declared in the spring standard way and * can be located through {@link * WebApplicationContextUtils#getRequiredWebApplicationContext(ServletContext)} * * @param webapp * wicket web application */ public TuscanyComponentInjector(WebApplication webapp) { // locate application context through spring's default location // mechanism and pass it on to the proper constructor this(webapp, webapp.getServletContext()); } /** * Constructor * * @param webapp * wicket web application * @param ctx * spring's application context */ public TuscanyComponentInjector(WebApplication webapp, ServletContext ctx) { if (webapp == null) { throw new IllegalArgumentException("Argument [[webapp]] cannot be null"); } if (ctx == null) { throw new IllegalArgumentException("Argument [[ctx]] cannot be null"); } // store context in application's metadata ... webapp.setMetaData(CONTEXT_KEY, new ApplicationContextHolder(ctx)); // ... and create and register the annotation aware injector InjectorHolder.setInjector(new TuscanyInjector(new ContextLocator())); } /** * This is a holder for the application context. The reason we need a holder is that metadata * only supports storing serializable objects but application context is not. The holder acts as * a serializable wrapper for the context. Notice that although holder implements IClusterable * it really is not because it has a reference to non serializable context - but this is ok * because metadata objects in application are never serialized. * * @author ivaynberg * */ private static class ApplicationContextHolder implements IClusterable { private static final long serialVersionUID = 1L; private final ServletContext context; /** * Constructor * * @param context */ public ApplicationContextHolder(ServletContext context) { this.context = context; } /** * @return the context */ public ServletContext getContext() { return context; } } /** * A context locator that locates the context in application's metadata. This locator also keeps * a transient cache of the lookup. * * @author ivaynberg * */ private static class ContextLocator implements IContextLocator { private transient ServletContext context; private static final long serialVersionUID = 1L; public ServletContext getServletContext() { if (context == null) { context = (Application.get().getMetaData(CONTEXT_KEY)).getContext(); } return context; } } }