/* * Copyright 2004-2012 the Seasar Foundation and the Others. * * Licensed 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.seasar.mayaa.impl.cycle; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.commons.collections.map.AbstractReferenceMap; import org.apache.commons.collections.map.ReferenceMap; import org.seasar.mayaa.cycle.ServiceCycle; import org.seasar.mayaa.cycle.scope.AttributeScope; import org.seasar.mayaa.cycle.script.CompiledScript; import org.seasar.mayaa.cycle.script.ScriptEnvironment; import org.seasar.mayaa.engine.processor.ProcessorTreeWalker; import org.seasar.mayaa.engine.specification.NodeTreeWalker; import org.seasar.mayaa.impl.CONST_IMPL; import org.seasar.mayaa.impl.ParameterAwareImpl; import org.seasar.mayaa.impl.cycle.scope.ScopeNotFoundException; import org.seasar.mayaa.impl.cycle.script.rhino.PageAttributeScope; import org.seasar.mayaa.impl.engine.EngineUtil; import org.seasar.mayaa.impl.provider.ProviderUtil; import org.seasar.mayaa.impl.source.ApplicationSourceDescriptor; import org.seasar.mayaa.impl.source.SourceUtil; import org.seasar.mayaa.impl.util.StringUtil; import org.seasar.mayaa.source.SourceDescriptor; /** * @author Masataka Kurihara (Gluegent, Inc.) */ public abstract class AbstractServiceCycle extends ParameterAwareImpl implements ServiceCycle, CONST_IMPL { private static final long serialVersionUID = -4084527796306356704L; private static final Map _scriptCache = Collections.synchronizedMap(new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.SOFT, true)); private AttributeScope _page; private NodeTreeWalker _originalNode; private NodeTreeWalker _injectedNode; private ProcessorTreeWalker _processor; private Throwable _t; public void load(String systemID) { load(systemID, SCRIPT_DEFAULT_CHARSET); } public void load(String systemID, String encoding) { if (StringUtil.isEmpty(systemID)) { throw new ScriptFileNotFoundException(systemID); } String sid = systemID; if (sid.startsWith("/WEB-INF/")) { sid = sid.substring(9); } else if (StringUtil.isRelativePath(sid)) { String sourcePath = EngineUtil.getSourcePath(); sid = StringUtil.adjustRelativePath(sourcePath, sid); } CompiledScript script = getScript(sid, encoding); if (script == null) { throw new ScriptFileNotFoundException(systemID); } script.execute(null); } protected CompiledScript getScript(String systemID, String encoding) { CompiledScript script = (CompiledScript) _scriptCache.get(systemID); if (script != null) { return script; } ApplicationSourceDescriptor appSource = new ApplicationSourceDescriptor(); if (systemID.startsWith("/") == false) { appSource.setRoot(ApplicationSourceDescriptor.WEB_INF); } appSource.setSystemID(systemID); SourceDescriptor source; if (appSource.exists()) { source = appSource; } else { source = SourceUtil.getSourceDescriptor(systemID); if (source.exists() == false) { return null; } } ScriptEnvironment env = ProviderUtil.getScriptEnvironment(); script = env.compile(source, encoding); _scriptCache.put(systemID, script); return script; } public Iterator iterateAttributeScope() { Iterator it = ProviderUtil.getScriptEnvironment().iterateAttributeScope(); return new ScopeIterator(this, it); } private static String ATTRIBUTE_SCOPE_CACHE_KEY = "ATTRIBUTE_SCOPE_CACHE"; static { CycleUtil.registVariableFactory(ATTRIBUTE_SCOPE_CACHE_KEY, new DefaultCycleLocalInstantiator() { public Object create(Object[] params) { return new HashMap(); } }); } private Map getAttributeScopeCacheMap() { return (Map) CycleUtil.getGlobalVariable(ATTRIBUTE_SCOPE_CACHE_KEY, null); } public AttributeScope findAttributeScope(String scopeName) { boolean currentPageScope = false; if (scopeName == null) { currentPageScope = true; scopeName = ServiceCycle.SCOPE_PAGE; } if (currentPageScope == false && getAttributeScopeCacheMap().containsKey(scopeName)) { return (AttributeScope) getAttributeScopeCacheMap().get(scopeName); } for (Iterator it = iterateAttributeScope(); it.hasNext();) { AttributeScope scope = (AttributeScope) it.next(); if (scope.getScopeName().equals(scopeName)) { if (currentPageScope) { scope = (AttributeScope)scope.getAttribute( PageAttributeScope.KEY_CURRENT); return scope; } getAttributeScopeCacheMap().put(scopeName, scope); return scope; } } getAttributeScopeCacheMap().put(scopeName, null); return null; } public boolean hasAttributeScope(String scopeName) { if (StringUtil.isEmpty(scopeName)) { //scopeName = ServiceCycle.SCOPE_PAGE; scopeName = null; } return findAttributeScope(scopeName) != null; } public AttributeScope getAttributeScope(String scopeName) { if (StringUtil.isEmpty(scopeName)) { //scopeName = ServiceCycle.SCOPE_PAGE; scopeName = null; } AttributeScope result = findAttributeScope(scopeName); if (result == null) { throw new ScopeNotFoundException(scopeName); } return result; } public void setPageScope(AttributeScope page) { if (page == null) { getAttributeScopeCacheMap().remove(ServiceCycle.SCOPE_PAGE); } else { getAttributeScopeCacheMap().put(ServiceCycle.SCOPE_PAGE, page); } _page = page; } public AttributeScope getPageScope() { return _page; } public void setOriginalNode(NodeTreeWalker originalNode) { _originalNode = originalNode; } public NodeTreeWalker getOriginalNode() { return _originalNode; } public void setInjectedNode(NodeTreeWalker injectedNode) { _injectedNode = injectedNode; } public NodeTreeWalker getInjectedNode() { return _injectedNode; } public void setProcessor(ProcessorTreeWalker processor) { _processor = processor; } public ProcessorTreeWalker getProcessor() { return _processor; } public void setHandledError(Throwable t) { _t = t; } public Throwable getHandledError() { return _t; } }