001    /*
002     * JBoss, Home of Professional Open Source.
003     * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004     * as indicated by the @author tags. See the copyright.txt file in the
005     * distribution for a full listing of individual contributors. 
006     *
007     * This is free software; you can redistribute it and/or modify it
008     * under the terms of the GNU Lesser General Public License as
009     * published by the Free Software Foundation; either version 2.1 of
010     * the License, or (at your option) any later version.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this software; if not, write to the Free
019     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021     */
022    package org.jboss.dna.graph;
023    
024    import java.security.AccessControlContext;
025    import javax.security.auth.Subject;
026    import javax.security.auth.login.LoginContext;
027    import org.jboss.dna.common.util.CheckArg;
028    import org.jboss.dna.common.util.Logger;
029    import org.jboss.dna.graph.properties.NameFactory;
030    import org.jboss.dna.graph.properties.NamespaceRegistry;
031    import org.jboss.dna.graph.properties.PathFactory;
032    import org.jboss.dna.graph.properties.PropertyFactory;
033    import org.jboss.dna.graph.properties.ValueFactories;
034    import org.jboss.dna.graph.properties.basic.DelegatingValueFactories;
035    
036    /**
037     * Utility methods for creating various execution contexts with replacement factories or components.
038     * 
039     * @author Randall Hauch
040     * @author John Verhaeg
041     */
042    public class ExecutionContexts {
043    
044        /**
045         * Create an context that can be used to replace the supplied context but that uses the supplied path factory.
046         * 
047         * @param context the base context
048         * @param pathFactory the new path factory
049         * @return the new execution context
050         * @throws IllegalArgumentException if the context or factory references are null
051         */
052        public static ExecutionContext replace( ExecutionContext context,
053                                                PathFactory pathFactory ) {
054            CheckArg.isNotNull(context, "context");
055            CheckArg.isNotNull(pathFactory, "pathFactory");
056            return new DelegatingExecutionEnvironment(context, null, null, null, pathFactory);
057        }
058    
059        /**
060         * Create an context that can be used to replace the supplied context but that uses the supplied name factory.
061         * 
062         * @param context the base context
063         * @param nameFactory the new name factory
064         * @return the new execution context
065         * @throws IllegalArgumentException if the context or factory references are null
066         */
067        public static ExecutionContext replace( ExecutionContext context,
068                                                NameFactory nameFactory ) {
069            CheckArg.isNotNull(context, "context");
070            CheckArg.isNotNull(nameFactory, "nameFactory");
071            return new DelegatingExecutionEnvironment(context, null, null, nameFactory, null);
072        }
073    
074        /**
075         * Create an context that can be used to replace the supplied context but that uses the supplied name and path factories.
076         * 
077         * @param context the base context
078         * @param nameFactory the new name factory
079         * @param pathFactory the new path factory
080         * @return the new execution context
081         * @throws IllegalArgumentException if the context or factory references are null
082         */
083        public static ExecutionContext replace( ExecutionContext context,
084                                                NameFactory nameFactory,
085                                                PathFactory pathFactory ) {
086            CheckArg.isNotNull(context, "context");
087            CheckArg.isNotNull(nameFactory, "nameFactory");
088            CheckArg.isNotNull(pathFactory, "pathFactory");
089            return new DelegatingExecutionEnvironment(context, null, null, nameFactory, pathFactory);
090        }
091    
092        /**
093         * Create an context that can be used to replace the supplied context but that uses the supplied namespace registry.
094         * 
095         * @param context the base context
096         * @param namespaceRegistry the new namespace registry
097         * @return the new execution context
098         * @throws IllegalArgumentException if the context or registry references are null
099         */
100        public static ExecutionContext replace( ExecutionContext context,
101                                                NamespaceRegistry namespaceRegistry ) {
102            CheckArg.isNotNull(context, "context");
103            CheckArg.isNotNull(namespaceRegistry, "namespaceRegistry");
104            return new DelegatingExecutionEnvironment(context, namespaceRegistry, null, null, null);
105        }
106    
107        protected static class DelegatingExecutionEnvironment implements ExecutionContext {
108    
109            private final ExecutionContext delegate;
110            private final NamespaceRegistry newNamespaceRegistry;
111            private final PropertyFactory newPropertyFactory;
112            private final ValueFactories newValueFactories;
113    
114            public DelegatingExecutionEnvironment( ExecutionContext delegate,
115                                                   NamespaceRegistry newRegistry,
116                                                   PropertyFactory newPropertyFactory,
117                                                   ValueFactories newValueFactories ) {
118                assert delegate != null;
119                this.delegate = delegate;
120                this.newNamespaceRegistry = newRegistry;
121                this.newPropertyFactory = newPropertyFactory;
122                this.newValueFactories = newValueFactories;
123            }
124    
125            public DelegatingExecutionEnvironment( ExecutionContext delegate,
126                                                   NamespaceRegistry newRegistry,
127                                                   PropertyFactory newPropertyFactory,
128                                                   final NameFactory newNameFactory,
129                                                   final PathFactory newPathFactory ) {
130                assert delegate != null;
131                this.delegate = delegate;
132                this.newNamespaceRegistry = newRegistry;
133                this.newPropertyFactory = newPropertyFactory;
134                final PathFactory pathFactory = newPathFactory != null ? newPathFactory : delegate.getValueFactories().getPathFactory();
135                final NameFactory nameFactory = newNameFactory != null ? newNameFactory : delegate.getValueFactories().getNameFactory();
136                this.newValueFactories = newPathFactory == null ? null : new DelegatingValueFactories(delegate.getValueFactories()) {
137    
138                    @Override
139                    public PathFactory getPathFactory() {
140                        return pathFactory;
141                    }
142    
143                    @Override
144                    public NameFactory getNameFactory() {
145                        return nameFactory;
146                    }
147                };
148            }
149    
150            /**
151             * {@inheritDoc}
152             * 
153             * @see org.jboss.dna.common.component.ClassLoaderFactory#getClassLoader(java.lang.String[])
154             */
155            public ClassLoader getClassLoader( String... classpath ) {
156                return this.delegate.getClassLoader(classpath);
157            }
158    
159            /**
160             * {@inheritDoc}
161             * 
162             * @see org.jboss.dna.graph.ExecutionContext#getAccessControlContext()
163             */
164            public AccessControlContext getAccessControlContext() {
165                return delegate.getAccessControlContext();
166            }
167    
168            /**
169             * {@inheritDoc}
170             * 
171             * @see org.jboss.dna.graph.ExecutionContext#getLoginContext()
172             */
173            public LoginContext getLoginContext() {
174                return delegate.getLoginContext();
175            }
176    
177            /**
178             * {@inheritDoc}
179             * 
180             * @see org.jboss.dna.graph.ExecutionContext#getNamespaceRegistry()
181             */
182            public NamespaceRegistry getNamespaceRegistry() {
183                if (newNamespaceRegistry != null) return newNamespaceRegistry;
184                return delegate.getNamespaceRegistry();
185            }
186    
187            /**
188             * {@inheritDoc}
189             * 
190             * @see org.jboss.dna.graph.ExecutionContext#getPropertyFactory()
191             */
192            public PropertyFactory getPropertyFactory() {
193                if (newPropertyFactory != null) return newPropertyFactory;
194                return delegate.getPropertyFactory();
195            }
196    
197            /**
198             * {@inheritDoc}
199             * 
200             * @see org.jboss.dna.graph.ExecutionContext#getValueFactories()
201             */
202            public ValueFactories getValueFactories() {
203                if (newValueFactories != null) return newValueFactories;
204                return delegate.getValueFactories();
205            }
206    
207            /**
208             * {@inheritDoc}
209             * 
210             * @see org.jboss.dna.graph.ExecutionContext#getSubject()
211             */
212            public Subject getSubject() {
213                return delegate.getSubject();
214            }
215    
216            /**
217             * {@inheritDoc}
218             * 
219             * @see org.jboss.dna.graph.ExecutionContext#getLogger(java.lang.Class)
220             */
221            public Logger getLogger( Class<?> clazz ) {
222                return delegate.getLogger(clazz);
223            }
224    
225            /**
226             * {@inheritDoc}
227             * 
228             * @see org.jboss.dna.graph.ExecutionContext#getLogger(java.lang.String)
229             */
230            public Logger getLogger( String name ) {
231                return delegate.getLogger(name);
232            }
233    
234            /**
235             * @return delegate
236             */
237            protected ExecutionContext getDelegate() {
238                return delegate;
239            }
240        }
241    }