public BaseSettingsApi( BuildSettings settings, GrailsBuildEventListener buildEventListener, boolean interactive) { buildSettings = settings; buildProps = buildSettings.getConfig().toProperties(); grailsHome = buildSettings.getGrailsHome(); metadataFile = new File(buildSettings.getBaseDir(), "application.properties"); metadata = metadataFile.exists() ? Metadata.getInstance(metadataFile) : Metadata.getCurrent(); metadataFile = metadata.getMetadataFile(); enableProfile = Boolean.valueOf(getPropertyValue("grails.script.profile", false).toString()); pluginsHome = buildSettings.getProjectPluginsDir().getPath(); pluginSettings = GrailsPluginUtils.getPluginBuildSettings(settings); grailsAppName = metadata.getApplicationName(); isInteractive = interactive; // If no app name property (upgraded/new/edited project) default to basedir. if (grailsAppName == null) { grailsAppName = buildSettings.getBaseDir().getName(); } if (grailsAppName.indexOf('/') > -1) { appClassName = grailsAppName.substring(grailsAppName.lastIndexOf('/'), grailsAppName.length()); } else { appClassName = GrailsNameUtils.getClassNameRepresentation(grailsAppName); } configSlurper = buildSettings.createConfigSlurper(); configSlurper.setEnvironment(buildSettings.getGrailsEnv()); this.buildEventListener = buildEventListener; }
public void updateMetadata( @SuppressWarnings("hiding") Metadata metadata, @SuppressWarnings("rawtypes") Map entries) { for (Object key : entries.keySet()) { final Object value = entries.get(key); if (value != null) { metadata.put(key, value.toString()); } } metadata.persist(); }
@Override public void setResourceLoader(ResourceLoader resourceLoader) { if (Metadata.getCurrent().isWarDeployed()) { localResourceLoader = resourceLoader; } else { // The "settings" may be null in some of the Grails unit tests. BuildSettings settings = BuildSettingsHolder.getSettings(); String location = null; if (settings != null) { location = settings.getResourcesDir().getPath(); } else if (Environment.getCurrent().isReloadEnabled()) { location = Environment.getCurrent().getReloadLocation(); } if (location != null) { localResourceLoader = new DevelopmentResourceLoader(application, location); } else { localResourceLoader = resourceLoader; } } super.setResourceLoader(localResourceLoader); if (resourceResolver == null) { resourceResolver = new PathMatchingResourcePatternResolver(localResourceLoader); } }
private Resource getResourceWithinContext(String uri) { if (resourceLoader == null) throw new IllegalStateException( "TemplateEngine not initialised correctly, no [resourceLoader] specified!"); if (Environment.getCurrent().isReloadEnabled() && Metadata.getCurrent().isWarDeployed()) { return resourceLoader.getResource(uri); } Resource r = servletContextLoader.getResource(uri); if (r.exists()) return r; return resourceLoader.getResource(uri); }
protected void syncAppVersion() { final Metadata metadata = Metadata.getInstance(new File(getBasedir(), "application.properties")); if (syncVersion(metadata)) metadata.persist(); String artifactId = project.getArtifactId(); if (artifactId.startsWith("grails-")) artifactId = artifactId.substring("grails-".length()); final String fName = getFullGrailsPluginName(); if (fName != null) { File gpFile = new File(fName); String text = null; String mod = null; try { text = readFileAsString(gpFile); mod = text.replaceFirst(GRAILS_PLUGIN_VERSION_PATTERN, "$1" + project.getVersion() + "$5"); } catch (IOException e) { // ignore } if (text != null && !mod.equalsIgnoreCase(text)) { BufferedOutputStream out = null; try { out = new BufferedOutputStream(new FileOutputStream(gpFile)); out.write(mod.getBytes()); } catch (IOException e) { // do nuffink } finally { if (out != null) { try { out.close(); } catch (Exception ignored) { // ignored } } } } } }
private boolean syncVersion(Metadata metadata) { boolean changed = false; Object apGrailsVersion = metadata.get(APP_GRAILS_VERSION); Artifact grailsDependency = findGrailsDependency(project); if (grailsDependency != null) { if (!grailsDependency.getVersion().equals(apGrailsVersion)) { metadata.put(APP_GRAILS_VERSION, grailsDependency.getVersion()); changed = true; } } else if (grailsVersion != null && !grailsVersion.equals(apGrailsVersion)) { metadata.put(APP_GRAILS_VERSION, grailsVersion); changed = true; } if (!project.getVersion().equals(metadata.get(APP_VERSION))) { metadata.put(APP_VERSION, project.getVersion()); changed = true; } return changed; }
private boolean enableDocumentationGeneration() { return !Metadata.getCurrent().isWarDeployed() && isBasePlugin(); }
@SuppressWarnings("unchecked") private void evaluateOnChangeListener() { if (pluginBean.isReadableProperty(ON_SHUTDOWN)) { onShutdownListener = (Closure) GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(plugin, ON_SHUTDOWN); } if (pluginBean.isReadableProperty(ON_CONFIG_CHANGE)) { onConfigChangeListener = (Closure) GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(plugin, ON_CONFIG_CHANGE); } if (pluginBean.isReadableProperty(ON_CHANGE)) { onChangeListener = (Closure) GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(plugin, ON_CHANGE); } final boolean warDeployed = Metadata.getCurrent().isWarDeployed(); final boolean reloadEnabled = Environment.getCurrent().isReloadEnabled(); if (!((reloadEnabled || !warDeployed) && onChangeListener != null)) { return; } Object referencedResources = GrailsClassUtils.getPropertyOrStaticPropertyOrFieldValue(plugin, WATCHED_RESOURCES); try { List resourceList = null; if (referencedResources instanceof String) { if (LOG.isDebugEnabled()) { LOG.debug( "Configuring plugin " + this + " to watch resources with pattern: " + referencedResources); } resourceList = new ArrayList(); resourceList.add(referencedResources.toString()); } else if (referencedResources instanceof List) { resourceList = (List) referencedResources; } if (resourceList != null) { List<String> resourceListTmp = new ArrayList<String>(); PluginBuildSettings pluginBuildSettings = GrailsPluginUtils.getPluginBuildSettings(); if (pluginBuildSettings != null) { final Resource[] pluginDirs = pluginBuildSettings.getPluginDirectories(); final Environment env = Environment.getCurrent(); final String baseLocation = env.getReloadLocation(); for (Object ref : resourceList) { String stringRef = ref.toString(); if (!warDeployed) { for (Resource pluginDir : pluginDirs) { if (pluginDir != null) { String pluginResources = getResourcePatternForBaseLocation( pluginDir.getFile().getCanonicalPath(), stringRef); resourceListTmp.add(pluginResources); } } addBaseLocationPattern(resourceListTmp, baseLocation, stringRef); } else { addBaseLocationPattern(resourceListTmp, baseLocation, stringRef); } } watchedResourcePatternReferences = new String[resourceListTmp.size()]; for (int i = 0; i < watchedResourcePatternReferences.length; i++) { String resRef = resourceListTmp.get(i); watchedResourcePatternReferences[i] = resRef; } watchedResourcePatterns = new WatchPatternParser() .getWatchPatterns(Arrays.asList(watchedResourcePatternReferences)); } } } catch (IllegalArgumentException e) { if (GrailsUtil.isDevelopmentEnv()) { LOG.debug( "Cannot load plug-in resource watch list from [" + ArrayUtils.toString(watchedResourcePatternReferences) + "]. This means that the plugin " + this + ", will not be able to auto-reload changes effectively. Try runnng grails upgrade.: " + e.getMessage()); } } catch (IOException e) { if (GrailsUtil.isDevelopmentEnv()) { LOG.debug( "Cannot load plug-in resource watch list from [" + ArrayUtils.toString(watchedResourcePatternReferences) + "]. This means that the plugin " + this + ", will not be able to auto-reload changes effectively. Try runnng grails upgrade.: " + e.getMessage()); } } }
/** * Default implementation of the GrailsApplication interface that manages application loading, * state, and artefact instances. * * <p>Upon loading this GrailsApplication will inspect each class using its registered * ArtefactHandler instances. Each ArtefactHandler provides knowledge about the conventions used to * establish its artefact type. For example controllers use the ControllerArtefactHandler to * establish this knowledge. * * <p>New ArtefactHandler instances can be registered with the GrailsApplication thus allowing * application extensibility. * * @author Marc Palmer * @author Steven Devijver * @author Graeme Rocher * @see org.codehaus.groovy.grails.plugins.GrailsPluginManager * @see org.codehaus.groovy.grails.plugins.DefaultGrailsPluginManager * @see org.codehaus.groovy.grails.commons.ArtefactHandler * @see org.codehaus.groovy.grails.commons.ArtefactInfo * @since 0.1 */ public class DefaultGrailsApplication extends GroovyObjectSupport implements GrailsApplication, BeanClassLoaderAware { protected static final Pattern GETCLASSESPROP_PATTERN = Pattern.compile("(\\w+)(Classes)"); protected static final Pattern GETCLASSESMETH_PATTERN = Pattern.compile("(get)(\\w+)(Classes)"); protected static final Pattern ISCLASS_PATTERN = Pattern.compile("(is)(\\w+)(Class)"); protected static final Pattern GETCLASS_PATTERN = Pattern.compile("(get)(\\w+)Class"); protected ClassLoader cl; protected Class<?>[] allClasses = new Class[0]; protected static Log log = LogFactory.getLog(DefaultGrailsApplication.class); protected ApplicationContext parentContext; protected ApplicationContext mainContext; protected List<Class<?>> loadedClasses = new ArrayList<Class<?>>(); protected ArtefactHandler[] artefactHandlers; protected Map<String, ArtefactHandler> artefactHandlersByName = new HashMap<String, ArtefactHandler>(); protected List<Class<?>> allArtefactClasses = new ArrayList<Class<?>>(); protected Map<String, ArtefactInfo> artefactInfo = new HashMap<String, ArtefactInfo>(); protected Class<?>[] allArtefactClassesArray; protected Metadata applicationMeta = Metadata.getCurrent(); protected Resource[] resources; protected boolean initialised = false; protected ConfigObject config; @SuppressWarnings("rawtypes") protected Map flatConfig = Collections.emptyMap(); /** Creates a new empty Grails application. */ public DefaultGrailsApplication() { cl = new GroovyClassLoader(); } /** * Creates a new GrailsApplication instance using the given classes and GroovyClassLoader. * * @param classes The classes that make up the GrailsApplication * @param classLoader The GroovyClassLoader to use */ public DefaultGrailsApplication(final Class<?>[] classes, ClassLoader classLoader) { Assert.notNull(classes, "Constructor argument 'classes' cannot be null"); loadedClasses.addAll(Arrays.asList(classes)); allClasses = classes; cl = classLoader; } /** * Loads a GrailsApplication using the given ResourceLocator instance which will search for * appropriate class names */ public DefaultGrailsApplication(Resource[] resources) { this(); for (Resource resource : resources) { Class<?> aClass; try { aClass = cl.loadClass( org.codehaus.groovy.grails.io.support.GrailsResourceUtils.getClassName( resource.getFile().getAbsolutePath())); } catch (ClassNotFoundException e) { throw new GrailsConfigurationException( "Class not found loading Grails application: " + e.getMessage(), e); } catch (IOException e) { throw new GrailsConfigurationException( "Class not found loading Grails application: " + e.getMessage(), e); } loadedClasses.add(aClass); } } /** * Loads a GrailsApplication using the given ResourceLocator instance which will search for * appropriate class names */ public DefaultGrailsApplication(org.codehaus.groovy.grails.io.support.Resource[] resources) { this(); for (org.codehaus.groovy.grails.io.support.Resource resource : resources) { Class<?> aClass; try { aClass = cl.loadClass( org.codehaus.groovy.grails.io.support.GrailsResourceUtils.getClassName( resource.getFile().getAbsolutePath())); } catch (ClassNotFoundException e) { throw new GrailsConfigurationException( "Class not found loading Grails application: " + e.getMessage(), e); } catch (IOException e) { throw new GrailsConfigurationException( "Class not found loading Grails application: " + e.getMessage(), e); } loadedClasses.add(aClass); } } /** * Initialises the default set of ArtefactHandler instances. * * @see org.codehaus.groovy.grails.commons.ArtefactHandler */ protected void initArtefactHandlers() { final DomainClassArtefactHandler domainClassArtefactHandler = new AnnotationDomainClassArtefactHandler(); if (!hasArtefactHandler(domainClassArtefactHandler.getType())) { registerArtefactHandler(domainClassArtefactHandler); } final ControllerArtefactHandler controllerArtefactHandler = new ControllerArtefactHandler(); if (!hasArtefactHandler(controllerArtefactHandler.getType())) { registerArtefactHandler(controllerArtefactHandler); } final ServiceArtefactHandler serviceArtefactHandler = new ServiceArtefactHandler(); if (!hasArtefactHandler(serviceArtefactHandler.getType())) { registerArtefactHandler(serviceArtefactHandler); } final TagLibArtefactHandler tagLibArtefactHandler = new TagLibArtefactHandler(); if (!hasArtefactHandler(tagLibArtefactHandler.getType())) { registerArtefactHandler(tagLibArtefactHandler); } final BootstrapArtefactHandler bootstrapArtefactHandler = new BootstrapArtefactHandler(); if (!hasArtefactHandler(bootstrapArtefactHandler.getType())) { registerArtefactHandler(bootstrapArtefactHandler); } final CodecArtefactHandler codecArtefactHandler = new CodecArtefactHandler(); if (!hasArtefactHandler(codecArtefactHandler.getType())) { registerArtefactHandler(codecArtefactHandler); } final UrlMappingsArtefactHandler urlMappingsArtefactHandler = new UrlMappingsArtefactHandler(); if (!hasArtefactHandler(urlMappingsArtefactHandler.getType())) { registerArtefactHandler(urlMappingsArtefactHandler); } updateArtefactHandlers(); } private void updateArtefactHandlers() { // Cache the list as an array artefactHandlers = artefactHandlersByName.values().toArray(new ArtefactHandler[artefactHandlersByName.size()]); } /** * Returns all the classes identified as artefacts by ArtefactHandler instances. * * @return An array of classes */ public Class<?>[] getAllArtefacts() { return allArtefactClassesArray; } protected Class<?>[] populateAllClasses() { allClasses = loadedClasses.toArray(new Class[loadedClasses.size()]); return allClasses; } /** * Configures the loaded classes within the GrailsApplication instance using the registered * ArtefactHandler instances. * * @param classes The classes to configure */ protected void configureLoadedClasses(Class<?>[] classes) { initArtefactHandlers(); artefactInfo.clear(); allArtefactClasses.clear(); allArtefactClassesArray = null; allClasses = classes; // first load the domain classes log.debug("Going to inspect artefact classes."); for (final Class<?> theClass : classes) { log.debug("Inspecting [" + theClass.getName() + "]"); if (allArtefactClasses.contains(theClass)) { continue; } // check what kind of artefact it is and add to corrent data structure for (ArtefactHandler artefactHandler : artefactHandlers) { if (artefactHandler.isArtefact(theClass)) { log.debug("Adding artefact " + theClass + " of kind " + artefactHandler.getType()); GrailsClass gclass = addArtefact(artefactHandler.getType(), theClass); // Also maintain set of all artefacts (!= all classes loaded) allArtefactClasses.add(theClass); // Update per-artefact cache DefaultArtefactInfo info = getArtefactInfo(artefactHandler.getType(), true); info.addGrailsClass(gclass); break; } } } refreshArtefactGrailsClassCaches(); allArtefactClassesArray = allArtefactClasses.toArray(new Class[allArtefactClasses.size()]); // Tell all artefact handlers to init now we've worked out which classes are which artefacts for (ArtefactHandler artefactHandler : artefactHandlers) { initializeArtefacts(artefactHandler); } } /** * Tell all our artefact info objects to update their internal state after we've added a bunch of * classes. */ protected void refreshArtefactGrailsClassCaches() { for (Object o : artefactInfo.values()) { ((DefaultArtefactInfo) o).updateComplete(); } } protected void addToLoaded(Class<?> clazz) { loadedClasses.add(clazz); populateAllClasses(); } public ClassLoader getClassLoader() { return cl; } public ConfigObject getConfig() { if (config == null) { setConfig(ConfigurationHelper.loadConfigFromClasspath(this)); } return config; } public void setConfig(ConfigObject config) { this.config = config; if (config == null) { flatConfig = Collections.emptyMap(); } else { flatConfig = config.flatten(); } } @SuppressWarnings("unchecked") public Map<String, Object> getFlatConfig() { return flatConfig; } /** * Retrieves the number of artefacts registered for the given artefactType as defined by the * ArtefactHandler. * * @param artefactType The type of the artefact as defined by the ArtefactHandler * @return The number of registered artefacts */ protected int getArtefactCount(String artefactType) { ArtefactInfo info = getArtefactInfo(artefactType); return info == null ? 0 : info.getClasses().length; } /** * Retrieves all classes loaded by the GrailsApplication. * * @return All classes loaded by the GrailsApplication */ public Class<?>[] getAllClasses() { return allClasses; } public ApplicationContext getMainContext() { return mainContext; } public void setMainContext(ApplicationContext context) { mainContext = context; } /** * Sets the parent ApplicationContext for the GrailsApplication. * * @param applicationContext The ApplicationContext * @throws BeansException Thrown when an error occurs setting the ApplicationContext */ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { parentContext = applicationContext; } /** * Retrieves the parent ApplicationContext for this GrailsApplication. * * @return The parent ApplicationContext */ public ApplicationContext getParentContext() { return parentContext; } /** * Retrieves a class from the GrailsApplication for the given name. * * @param className The class name * @return Either the Class instance or null if it doesn't exist */ public Class<?> getClassForName(String className) { if (StringUtils.isBlank(className)) { return null; } for (Class<?> c : allClasses) { if (c.getName().equals(className)) { return c; } } return null; } /** * Refreshes constraints defined by the DomainClassArtefactHandler. * * <p>TODO: Move this out of GrailsApplication */ public void refreshConstraints() { ArtefactInfo info = getArtefactInfo(DomainClassArtefactHandler.TYPE, true); GrailsClass[] domainClasses = info.getGrailsClasses(); for (GrailsClass domainClass : domainClasses) { ((GrailsDomainClass) domainClass).refreshConstraints(); } } /** * Refreshes this GrailsApplication, rebuilding all of the artefact definitions as defined by the * registered ArtefactHandler instances. */ public void refresh() { if (cl instanceof GroovyClassLoader) { configureLoadedClasses(((GroovyClassLoader) cl).getLoadedClasses()); } } public void rebuild() { initialised = false; loadedClasses.clear(); initArtefactHandlers(); if (GrailsUtil.isDevelopmentEnv()) { initialise(); } else { throw new IllegalStateException( "Cannot rebuild GrailsApplication when not in development mode!"); } } /** * Retrieves the Spring Resource that was used to load the given Class. * * @param theClazz The class * @return Either a Spring Resource or null if no Resource was found for the given class */ public Resource getResourceForClass(@SuppressWarnings("rawtypes") Class theClazz) { // TODO fix return null; } /** * Returns true if the given class is an artefact identified by one of the registered * ArtefactHandler instances. Uses class name equality to handle class reloading * * @param theClazz The class to check * @return true if it is an artefact */ public boolean isArtefact(@SuppressWarnings("rawtypes") Class theClazz) { String className = theClazz.getName(); for (Class<?> artefactClass : allArtefactClasses) { if (className.equals(artefactClass.getName())) { return true; } } return false; } /** * Returns true if the specified class is of the given artefact type as defined by the * ArtefactHandler. * * @param artefactType The type of the artefact * @param theClazz The class * @return true if it is of the specified artefactType * @see org.codehaus.groovy.grails.commons.ArtefactHandler */ public boolean isArtefactOfType( String artefactType, @SuppressWarnings("rawtypes") Class theClazz) { ArtefactHandler handler = artefactHandlersByName.get(artefactType); if (handler == null) { throw new GrailsConfigurationException( "Unable to locate arefact handler for specified type: " + artefactType); } return handler.isArtefact(theClazz); } /** * Returns true if the specified class name is of the given artefact type as defined by the * ArtefactHandler. * * @param artefactType The type of the artefact * @param className The class name * @return true if it is of the specified artefactType * @see org.codehaus.groovy.grails.commons.ArtefactHandler */ public boolean isArtefactOfType(String artefactType, String className) { return getArtefact(artefactType, className) != null; } /** * Retrieves an artefact for the given type and name. * * @param artefactType The artefact type as defined by a registered ArtefactHandler * @param name The name of the class * @return A GrailsClass instance or null if none could be found for the given artefactType and * name */ public GrailsClass getArtefact(String artefactType, String name) { ArtefactInfo info = getArtefactInfo(artefactType); return info == null ? null : info.getGrailsClass(name); } public ArtefactHandler getArtefactType(@SuppressWarnings("rawtypes") Class theClass) { for (ArtefactHandler artefactHandler : artefactHandlers) { if (artefactHandler.isArtefact(theClass)) { return artefactHandler; } } return null; } protected GrailsClass getFirstArtefact(String artefactType) { ArtefactInfo info = getArtefactInfo(artefactType); // This will throw AIOB if we have none return info == null ? null : info.getGrailsClasses()[0]; } /** * Returns all of the GrailsClass instances for the given artefactType as defined by the * ArtefactHandler * * @param artefactType The type of the artefact defined by the ArtefactHandler * @return An array of classes for the given artefact */ public GrailsClass[] getArtefacts(String artefactType) { return getArtefactInfo(artefactType, true).getGrailsClasses(); } // This is next call is equiv to getControllerByURI / getTagLibForTagName public GrailsClass getArtefactForFeature(String artefactType, Object featureID) { return artefactHandlersByName.get(artefactType).getArtefactForFeature(featureID); } /** * Adds an artefact of the given type for the given Class. * * @param artefactType The type of the artefact as defined by a ArtefactHandler instance * @param artefactClass A Class instance that matches the type defined by the ArtefactHandler * @return The GrailsClass if successful or null if it couldn't be added * @throws GrailsConfigurationException If the specified Class is not the same as the type defined * by the ArtefactHandler * @see org.codehaus.groovy.grails.commons.ArtefactHandler */ public GrailsClass addArtefact( String artefactType, @SuppressWarnings("rawtypes") Class artefactClass) { return addArtefact(artefactType, artefactClass, false); } /** * Adds an artefact of the given type for the given GrailsClass. * * @param artefactType The type of the artefact as defined by a ArtefactHandler instance * @param artefactGrailsClass A GrailsClass instance that matches the type defined by the * ArtefactHandler * @return The GrailsClass if successful or null if it couldn't be added * @throws GrailsConfigurationException If the specified GrailsClass is not the same as the type * defined by the ArtefactHandler * @see org.codehaus.groovy.grails.commons.ArtefactHandler */ public GrailsClass addArtefact(String artefactType, GrailsClass artefactGrailsClass) { ArtefactHandler handler = artefactHandlersByName.get(artefactType); if (handler.isArtefactGrailsClass(artefactGrailsClass)) { // Store the GrailsClass in cache DefaultArtefactInfo info = getArtefactInfo(artefactType, true); info.addGrailsClass(artefactGrailsClass); info.updateComplete(); initializeArtefacts(artefactType); return artefactGrailsClass; } throw new GrailsConfigurationException( "Cannot add " + artefactType + " class [" + artefactGrailsClass + "]. It is not a " + artefactType + "!"); } /** * Registers a new ArtefactHandler that is responsible for identifying and managing a particular * artefact type that is defined by some convention. * * @param handler The ArtefactHandler to regster */ public void registerArtefactHandler(ArtefactHandler handler) { GrailsApplicationAwareBeanPostProcessor.processAwareInterfaces(this, handler); artefactHandlersByName.put(handler.getType(), handler); updateArtefactHandlers(); } public boolean hasArtefactHandler(String type) { return artefactHandlersByName.containsKey(type); } public ArtefactHandler[] getArtefactHandlers() { return artefactHandlers; } public ArtefactHandler getArtefactHandler(String type) { return artefactHandlersByName.get(type); } /** * Re-initialize the artefacts of the specified type. This gives handlers a chance to update * caches etc. * * @param artefactType The type of artefact to init */ protected void initializeArtefacts(String artefactType) { initializeArtefacts(artefactHandlersByName.get(artefactType)); } /** * Clears the application returning it to an empty state. Very dangerous method, use with caution. */ public void clear() { artefactHandlersByName.clear(); updateArtefactHandlers(); artefactInfo.clear(); initialise(); } /** * Re-initialize the artefacts of the specified type. This gives handlers a chance to update * caches etc. * * @param handler The handler to register */ protected void initializeArtefacts(ArtefactHandler handler) { if (handler == null) { return; } ArtefactInfo info = getArtefactInfo(handler.getType()); // Only init those that have data if (info != null) { // System.out.println("Initialising artefacts of kind " + handler.getType() + " with // registered artefacts" + info.getGrailsClassesByName()); handler.initialize(info); } } /** * Get or create the cache of classes for the specified artefact type. * * @param artefactType The name of an artefact type * @param create Set to true if you want non-existent caches to be created * @return The cache of classes for the type, or null if no cache exists and create is false */ protected DefaultArtefactInfo getArtefactInfo(String artefactType, boolean create) { DefaultArtefactInfo cache = (DefaultArtefactInfo) artefactInfo.get(artefactType); if (cache == null && create) { cache = new DefaultArtefactInfo(); artefactInfo.put(artefactType, cache); cache.updateComplete(); } return cache; } /** * Get the cache of classes for the specified artefact type. * * @param artefactType The name of an artefact type * @return The cache of classes for the type, or null if no cache exists */ public ArtefactInfo getArtefactInfo(String artefactType) { return getArtefactInfo(artefactType, false); } /** * Overrides method invocation to return dynamic artefact methods. * * <p>We will support getXXXXClasses() and isXXXXClass(class) * * @param methodName The name of the method * @param args The arguments to the method * @return The return value of the method TODO Need to add matches for * add<Artefact>Class(java.lang.Class) and add<Artefact>Class(GrailsClass) */ @Override public Object invokeMethod(String methodName, Object args) { Object[] argsv = (Object[]) args; Matcher match = GETCLASS_PATTERN.matcher(methodName); // look for getXXXXClass(y) match.find(); if (match.matches()) { if (argsv.length > 0) { if (argsv[0] instanceof CharSequence) argsv[0] = argsv[0].toString(); if ((argsv.length != 1) || !(argsv[0] instanceof String)) { throw new IllegalArgumentException( "Dynamic method get<Artefact>Class(artefactName) requires a single String parameter"); } return getArtefact(match.group(2), argsv[0].toString()); } // It's a no-param getter return super.invokeMethod(methodName, args); } // look for isXXXXClass(y) match = ISCLASS_PATTERN.matcher(methodName); // find match match.find(); if (match.matches()) { if ((argsv.length != 1) || !(argsv[0] instanceof Class<?>)) { throw new IllegalArgumentException( "Dynamic method is<Artefact>Class(artefactClass) requires a single Class parameter"); } return isArtefactOfType(match.group(2), (Class<?>) argsv[0]); } // look for getXXXXClasses match = GETCLASSESMETH_PATTERN.matcher(methodName); // find match match.find(); if (match.matches()) { String artefactName = GrailsNameUtils.getClassNameRepresentation(match.group(2)); if (artefactHandlersByName.containsKey(artefactName)) { return getArtefacts(match.group(2)); } throw new IllegalArgumentException( "Dynamic method get<Artefact>Classes() called for " + "unrecognized artefact: " + match.group(2)); } return super.invokeMethod(methodName, args); } /** * Override property access and hit on xxxxClasses to return class arrays of artefacts. * * @param propertyName The name of the property, if it ends in *Classes then match and invoke * internal ArtefactHandler * @return All the artifacts or delegate to super.getProperty */ @Override public Object getProperty(String propertyName) { // look for getXXXXClasses final Matcher match = GETCLASSESPROP_PATTERN.matcher(propertyName); // find match match.find(); if (match.matches()) { String artefactName = GrailsNameUtils.getClassNameRepresentation(match.group(1)); if (artefactHandlersByName.containsKey(artefactName)) { return getArtefacts(artefactName); } } return super.getProperty(propertyName); } public void initialise() { // get all the classes that were loaded if (log.isDebugEnabled()) { log.debug("loaded classes: [" + loadedClasses + "]"); } Class<?>[] classes = populateAllClasses(); configureLoadedClasses(classes); initialised = true; } public boolean isInitialised() { return initialised; } public Metadata getMetadata() { return applicationMeta; } public GrailsClass getArtefactByLogicalPropertyName(String type, String logicalName) { ArtefactInfo info = getArtefactInfo(type); return info == null ? null : info.getGrailsClassByLogicalPropertyName(logicalName); } public void addArtefact(@SuppressWarnings("rawtypes") Class artefact) { for (ArtefactHandler artefactHandler : artefactHandlers) { if (artefactHandler.isArtefact(artefact)) { addArtefact(artefactHandler.getType(), artefact); } } } public boolean isWarDeployed() { return getMetadata().isWarDeployed(); } public void setBeanClassLoader(ClassLoader classLoader) { // do nothing } public void addOverridableArtefact(@SuppressWarnings("rawtypes") Class artefact) { for (ArtefactHandler artefactHandler : artefactHandlers) { if (artefactHandler.isArtefact(artefact)) { addOverridableArtefact(artefactHandler.getType(), artefact); } } } public void configChanged() { ConfigObject co = getConfig(); // not thread safe flatConfig = co.flatten(); final ArtefactHandler[] handlers = getArtefactHandlers(); for (ArtefactHandler handler : handlers) { if (handler instanceof GrailsConfigurationAware) { ((GrailsConfigurationAware) handler).setConfiguration(co); } } } /** * Adds an artefact of the given type for the given Class. * * @param artefactType The type of the artefact as defined by a ArtefactHandler instance * @param artefactClass A Class instance that matches the type defined by the ArtefactHandler * @return The GrailsClass if successful or null if it couldn't be added * @throws GrailsConfigurationException If the specified Class is not the same as the type defined * by the ArtefactHandler * @see org.codehaus.groovy.grails.commons.ArtefactHandler */ public GrailsClass addOverridableArtefact( String artefactType, @SuppressWarnings("rawtypes") Class artefactClass) { return addArtefact(artefactType, artefactClass, true); } protected GrailsClass addArtefact( String artefactType, Class<?> artefactClass, boolean overrideable) { ArtefactHandler handler = artefactHandlersByName.get(artefactType); if (handler.isArtefact(artefactClass)) { GrailsClass artefactGrailsClass = handler.newArtefactClass(artefactClass); artefactGrailsClass.setGrailsApplication(this); // Store the GrailsClass in cache DefaultArtefactInfo info = getArtefactInfo(artefactType, true); if (overrideable) { info.addOverridableGrailsClass(artefactGrailsClass); } else { info.addGrailsClass(artefactGrailsClass); } info.updateComplete(); addToLoaded(artefactClass); if (isInitialised()) { initializeArtefacts(artefactType); } return artefactGrailsClass; } throw new GrailsConfigurationException( "Cannot add " + artefactType + " class [" + artefactClass + "]. It is not a " + artefactType + "!"); } }
/** * Modifies the application's metadata, as stored in the "application.properties" file. If it * doesn't exist, the file is created. */ public void updateMetadata(@SuppressWarnings("rawtypes") Map entries) { @SuppressWarnings("hiding") Metadata metadata = Metadata.getCurrent(); updateMetadata(metadata, entries); }
public String getAppGrailsVersion() { return metadata.getGrailsVersion(); }
public String getGrailsAppVersion() { return metadata.getApplicationVersion(); }