public void buildSourceCode(String includingClassName) { long start = System.currentTimeMillis(); addVersion(); importPaths = new HashSet<String>(); // Possible bug here? if (null != codeBuilder) codeBuilder.clear(); codeBuilder = new CodeBuilder( templateResource.asTemplateContent(), name(), tagName(), this, engine, dialect); codeBuilder.includingCName = includingClassName; codeBuilder.build(); extendedTemplateClass = codeBuilder.getExtendedTemplateClass(); javaSource = codeBuilder.toString(); if (logger.isTraceEnabled()) { logger.trace( "%s ms to generate java source for template: %s", System.currentTimeMillis() - start, getKey()); } }
/** * @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); } }