summaryrefslogtreecommitdiffstats
path: root/java/sca/modules/wicket/src/main/java/org/apache/tuscany/sca/wicket/TuscanyComponentInjector.java
blob: b1e9097cdf155159ce7876f8a0ed1ca302cf632c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * 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
 * <code>addComponentInstantiationListener(new SpringComponentInjector(this));</code> Non-wicket
 * components such as {@link Session}, {@link Model}, and any other pojo can be injected by calling
 * <code>InjectorHolder.getInjector().inject(this)</code> 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<ApplicationContextHolder> CONTEXT_KEY = new MetaDataKey<ApplicationContextHolder>()
        {

                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;
                }

        }

}