001 /**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019 020 package org.apache.james.jspf.impl; 021 022 import org.apache.james.jspf.core.LogEnabled; 023 import org.apache.james.jspf.core.Logger; 024 import org.apache.james.jspf.core.exceptions.PermErrorException; 025 import org.apache.james.jspf.parser.TermDefinition; 026 import org.apache.james.jspf.parser.TermsFactory; 027 import org.apache.james.jspf.terms.Configuration; 028 import org.apache.james.jspf.terms.ConfigurationEnabled; 029 import org.apache.james.jspf.wiring.WiringService; 030 import org.apache.james.jspf.wiring.WiringServiceException; 031 import org.apache.james.jspf.wiring.WiringServiceTable; 032 033 import java.io.IOException; 034 import java.io.InputStream; 035 import java.util.ArrayList; 036 import java.util.Collection; 037 import java.util.Collections; 038 import java.util.Properties; 039 040 /** 041 * The default implementation of the TermsFactory 042 */ 043 public class DefaultTermsFactory implements TermsFactory { 044 045 private String termFile = "org/apache/james/jspf/parser/jspf.default.terms"; 046 047 private Collection<TermDefinition> mechanismsCollection; 048 049 private Collection<TermDefinition> modifiersCollection; 050 051 private Logger log; 052 053 private WiringService wiringService; 054 055 public DefaultTermsFactory(Logger log) { 056 this.log = log; 057 this.wiringService = new WiringServiceTable(); 058 ((WiringServiceTable) this.wiringService).put(LogEnabled.class, log); 059 init(); 060 } 061 062 public DefaultTermsFactory(Logger log, WiringService wiringService) { 063 this.log = log; 064 this.wiringService = wiringService; 065 init(); 066 } 067 068 /** 069 * Initialize the factory and the services 070 */ 071 private void init() { 072 try { 073 InputStream is = Thread.currentThread().getContextClassLoader() 074 .getResourceAsStream(termFile); 075 if (is == null) { 076 throw new NullPointerException("Unable to find the "+termFile+" resource in the classpath"); 077 } 078 Properties p = new Properties(); 079 p.load(is); 080 String mechs = p.getProperty("mechanisms"); 081 String mods = p.getProperty("modifiers"); 082 String[] classes; 083 classes = mechs.split(","); 084 Class<?>[] knownMechanisms = new Class[classes.length]; 085 for (int i = 0; i < classes.length; i++) { 086 log.debug("Add following class as known mechanismn: " 087 + classes[i]); 088 knownMechanisms[i] = Thread.currentThread() 089 .getContextClassLoader().loadClass(classes[i]); 090 } 091 mechanismsCollection = createTermDefinitionCollection(knownMechanisms); 092 classes = mods.split(","); 093 Class<?>[] knownModifiers = new Class[classes.length]; 094 for (int i = 0; i < classes.length; i++) { 095 log.debug("Add following class as known modifier: " 096 + classes[i]); 097 knownModifiers[i] = Thread.currentThread() 098 .getContextClassLoader().loadClass(classes[i]); 099 } 100 modifiersCollection = createTermDefinitionCollection(knownModifiers); 101 102 } catch (IOException e) { 103 throw new IllegalStateException( 104 "Term configuration cannot be found"); 105 } catch (ClassNotFoundException e) { 106 throw new IllegalStateException( 107 "One configured class cannot be found"); 108 } 109 } 110 111 112 /** 113 * Create a collection of term definitions supported by this factory. 114 * 115 * @param classes 116 * classes to analyze 117 * @param staticFieldName 118 * static field to concatenate 119 * @return map <Class,Pattern> 120 */ 121 private Collection<TermDefinition> createTermDefinitionCollection(Class<?>[] classes) { 122 Collection<TermDefinition> l = new ArrayList<TermDefinition>(); 123 for (int j = 0; j < classes.length; j++) { 124 try { 125 l.add(new DefaultTermDefinition(classes[j])); 126 } catch (Exception e) { 127 log.debug("Unable to create the term collection", e); 128 throw new IllegalStateException( 129 "Unable to create the term collection"); 130 } 131 } 132 return Collections.synchronizedCollection(l); 133 } 134 135 136 /** 137 * @see org.apache.james.jspf.parser.TermsFactory#createTerm(java.lang.Class, org.apache.james.jspf.terms.Configuration) 138 */ 139 public Object createTerm(Class<?> termDef, Configuration subres) throws PermErrorException, InstantiationException { 140 try { 141 Object term = termDef.newInstance(); 142 143 try { 144 wiringService.wire(term); 145 } catch (WiringServiceException e) { 146 throw new InstantiationException( 147 "Unexpected error adding dependencies to term: " + e.getMessage()); 148 } 149 150 if (term instanceof ConfigurationEnabled) { 151 if (subres == null || subres.groupCount() == 0) { 152 ((ConfigurationEnabled) term).config(null); 153 } else { 154 ((ConfigurationEnabled) term).config(subres); 155 } 156 } 157 return term; 158 } catch (IllegalAccessException e) { 159 throw new InstantiationException( 160 "Unexpected error creating term: " + e.getMessage()); 161 } 162 } 163 164 165 /** 166 * @see org.apache.james.jspf.parser.TermsFactory#getMechanismsCollection() 167 */ 168 public Collection<TermDefinition> getMechanismsCollection() { 169 return mechanismsCollection; 170 } 171 172 173 /** 174 * @see org.apache.james.jspf.parser.TermsFactory#getModifiersCollection() 175 */ 176 public Collection<TermDefinition> getModifiersCollection() { 177 return modifiersCollection; 178 } 179 180 }