View Javadoc
1   /*
2    * Copyright 2011 FatWire Corporation. All Rights Reserved.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.fatwire.gst.foundation.groovy;
18  
19  import groovy.util.GroovyScriptEngine;
20  
21  import java.io.IOException;
22  import java.util.Collections;
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import javax.servlet.ServletContext;
27  
28  import org.apache.commons.lang.StringUtils;
29  import org.apache.commons.logging.Log;
30  
31  import COM.FutureTense.Interfaces.ICS;
32  import COM.FutureTense.Interfaces.Utilities;
33  
34  import com.fatwire.cs.core.db.PreparedStmt;
35  import com.fatwire.cs.core.db.StatementParam;
36  import com.fatwire.gst.foundation.facade.logging.LogUtil;
37  import com.fatwire.gst.foundation.facade.runtag.render.LogDep;
38  import com.fatwire.gst.foundation.facade.sql.Row;
39  import com.fatwire.gst.foundation.facade.sql.SqlHelper;
40  
41  /**
42   * Loader for groovy script classes from the ElementCatalog
43   * 
44   * @author Dolf Dijkstra
45   * @since September 21,2012
46   */
47  /*
48   * alternative method:
49   * http://groovy.codehaus.org/Alternate+Spring-Groovy-Integration
50   */
51  public class GroovyElementCatalogLoader extends DiskGroovyLoader {
52  	private PreparedStmt stmt;
53  	private Log logger = LogUtil.getLog(getClass());
54  	private boolean isLoaded = false;
55  	private String path;
56  
57  	public GroovyElementCatalogLoader(ServletContext servletContext) {
58  		super(servletContext);
59  		/*
60  		 * ElementCatalog does not have Browser ACL, assumption here is that
61  		 * elements are updated as assets
62  		 */
63  		stmt = new PreparedStmt(
64  				"SELECT * FROM ElementCatalog WHERE elementname=?",
65  				Collections.singletonList("CSElement"));
66  		stmt.setElement(0, java.sql.Types.VARCHAR);
67  
68  	}
69  
70  	@Override
71  	public Object load(ICS ics, String resourceName) throws Exception {
72  		if (!isLoaded) {
73  			bootEngine(ics, path);
74  			isLoaded = true;
75  		}
76  
77  		if (logger.isDebugEnabled())
78  			logger.debug("Loading groovy script " + resourceName);
79  		if (ics.IsElement(resourceName)) {
80  
81  			final StatementParam param = stmt.newParam();
82  			param.setString(0, resourceName);
83  			Row row = SqlHelper.selectSingle(ics, stmt, param);
84  
85  			// ELEMENTNAME DESCRIPTION URL RESDETAILS1
86  			// RESDETAILS2
87  
88  			String url = row.getString("url");
89  			String res1 = row.getString("resdetails1");
90  			String res2 = row.getString("resdetails2");
91  			Map<String, String> m = new HashMap<String, String>();
92  			Utilities.getParams(res1, m, false);
93  			Utilities.getParams(res2, m, false);
94  			String tid = m.get("tid");
95  			String eid = m.get("eid");
96  			if (StringUtils.isNotBlank(tid)) {
97  				LogDep.logDep(ics, "Template", tid);
98  			}
99  			if (StringUtils.isNotBlank(eid)) {
100 				LogDep.logDep(ics, "CSElement", eid);
101 			}
102 			// prevent case where resourcename is same as a jsp element.
103 			if (url.endsWith(".groovy")) {
104 				// no loading based on fallback class name as the super method
105 				// has.
106 				if (logger.isDebugEnabled()) {
107 					logger.debug("Found element for " + resourceName + " => "
108 							+ url);
109 				}
110 				Class<?> x = getGroovyScriptEngine().loadScriptByName(url);
111 				return x.newInstance();
112 
113 			} else {
114 				return super.load(ics, resourceName);
115 			}
116 		} else {
117 			return super.load(ics, resourceName);
118 		}
119 
120 	}
121 
122 	@Override
123 	public void bootEngine(final String path) {
124 		this.path = path;
125 	}
126 
127 	public void bootEngine(ICS ics, final String path) {
128 		String[] root = new String[2];
129 
130 		String elementCatalogDefDir = ics
131 				.ResolveVariables("CS.CatalogDir.ElementCatalog");
132 		root[0] = elementCatalogDefDir;
133 		root[1] = path;
134 
135 		GroovyScriptEngine gse;
136 		try {
137 			gse = new GroovyScriptEngine(root, Thread.currentThread()
138 					.getContextClassLoader());
139 			gse.getConfig().setRecompileGroovySource(true);
140 			gse.getConfig().setMinimumRecompilationInterval(
141 					getMinimumRecompilationInterval());
142 			setGroovyScriptEngine(gse);
143 
144 		} catch (IOException e) {
145 			throw new RuntimeException(e);
146 		}
147 
148 	}
149 
150 }