public RawData postSep(String sep) { String result = ""; if (null != obj) { result += S.escape(obj); } return RawData.valueOf(result + (isLast ? "" : sep)); }
public RawData preSep(String sep) { String result = ""; if (null != obj) { result += S.escape(obj); } return RawData.valueOf(result); }
/** * Compile the class from Java source * * @return the bytes that comprise the class file */ public byte[] compile() { if (null != javaByteCode) return javaByteCode; if (null == javaSource) throw new IllegalStateException("Cannot find java source when compiling " + getKey()); compiling = true; long start = System.currentTimeMillis(); try { engine().classes.compiler.compile(new String[] {name()}); if (logger.isTraceEnabled()) { logger.trace("%sms to compile template: %s", System.currentTimeMillis() - start, getKey()); } } catch (CompileException.CompilerException e) { String cn = e.className; TemplateClass tc = S.isEqual(cn, name()) ? this : engine().classes.getByClassName(cn); if (null == tc) tc = this; CompileException ce = new CompileException( tc, e.javaLineNumber, e.message); // init ce before reset java source to get template line info if (engine().isProdMode()) { TextBuilder tb = new TextBuilder(); String[] lines = javaSource.split("(\\n\\r|\\r\\n|\\r|\\n)"); for (int line = 0; line < lines.length; ++line) { tb.p(line + 1).p(":").p(lines[line]).p("\n"); } logger.error("error compiling java source:\n%s", tb.toString()); } javaSource = null; // force parser to regenerate source. This helps to reload after fixing the tag file // compilation failure throw ce; } catch (NullPointerException e) { String clazzName = name(); TemplateClass tc = engine().classes.getByClassName(clazzName); if (this != tc) { logger.error("tc is not this"); } if (!this.equals(tc)) { logger.error("tc not match this"); } logger.error("NPE encountered when compiling template class:" + name()); throw e; } finally { compiling = false; } if (logger.isTraceEnabled()) { logger.trace( "%sms to compile template class %s", System.currentTimeMillis() - start, getKey()); } return javaByteCode; }
public void deserializeIncludeTagTypes(String s) { includeTagTypes = new HashMap<String, String>(); if (S.isEmpty(s)) return; String[] sa = s.split(";"); for (String s0 : sa) { String[] sa0 = s0.split(":"); if (sa0.length != 2) throw new IllegalArgumentException("Unknown include tag types string: " + s); includeTagTypes.put(sa0[0], sa0[1]); } }
/** * @return true if this class has changes refreshed, otherwise this class has not been changed yet */ public boolean refresh(boolean forceRefresh) { if (refreshing()) return false; if (inner) return false; try { RythmEngine e = engine(); refreshing(true); if (!templateResource.isValid()) { // it is removed? isValid = false; engine().classes.remove(this); return false; } if (null == name) { // this is the root level template class root = this; name = templateResource.getSuggestedClassName() + CN_SUFFIX; // name = templateResource.getSuggestedClassName(); if (e.reloadByIncClassVersion()) version = nextVersion.getAndIncrement(); engine().classes.add(this); } if (null == javaSource) { engine().classCache.loadTemplateClass(this); if (null != javaSource) { // try refresh extended template class if there is Pattern p = Pattern.compile( ".*extends\\s+([a-zA-Z0-9_]+)\\s*\\{\\s*\\/\\/<extended_resource_key\\>(.*)\\<\\/extended_resource_key\\>.*", Pattern.DOTALL); Matcher m = p.matcher(javaSource); if (m.matches()) { String extended = m.group(1); TemplateClassManager tcm = engine().classes; extendedTemplateClass = tcm.getByClassName(extended); if (null == extendedTemplateClass) { String extendedResourceKey = m.group(2); extendedTemplateClass = tcm.getByTemplate(extendedResourceKey); if (null == extendedTemplateClass) { extendedTemplateClass = new TemplateClass(extendedResourceKey, engine()); extendedTemplateClass.refresh(); } } engine().addExtendRelationship(extendedTemplateClass, this); } } } boolean extendedTemplateChanged = false; if (extendedTemplateClass != null) extendedTemplateChanged = extendedTemplateClass.refresh(forceRefresh); boolean includedTemplateChanged = false; if (includedTemplateClasses.size() == 0 && !S.isEmpty(includeTemplateClassNames) && !NO_INCLUDE_CLASS.equals(includeTemplateClassNames)) { // just loaded from persistent store for (String tcName : includeTemplateClassNames.split(",")) { if (S.isEmpty(tcName)) continue; tcName = tcName.trim(); String fullName = engine().testTag(tcName, this); if (null == fullName) { logger.warn("Unable to load included template class from name: %s", tcName); continue; } TemplateClass tc = engine().getTemplateClassFromTagName(fullName); if (null == tc) { logger.warn("Unable to load included template class from name: %s", tcName); continue; } includedTemplateClasses.add(tc); } } for (TemplateClass tc : includedTemplateClasses) { if (tc.refresh(forceRefresh)) { includedTemplateChanged = true; break; } } if (extendedTemplateChanged && engine().reloadByRestart() && !forceRefresh) { reset(); compiled = false; engine().restart(new ClassReloadException("extended class changed")); refreshing(false); refresh(forceRefresh); return true; // pass refresh state to sub template } // templateResource.refresh() must be put at first so we make sure resource get refreshed boolean resourceChanged = templateResource.refresh(); boolean refresh = resourceChanged || forceRefresh || (null == javaSource) || includedTemplateChanged || extendedTemplateChanged; if (!refresh) return false; // now start generate source and compile source to byte code reset(); buildSourceCode(); engine().classCache.cacheTemplateClassSource(this); // cache source code for debugging purpose if (!codeBuilder.isRythmTemplate()) { isValid = false; engine().classes.remove(this); return false; } isValid = true; // if (!engine().isProd Mode()) logger.info(javaSource); compiled = false; return true; } finally { refreshing(false); } }