*/
public synchronized boolean refresh(boolean forceRefresh) {
if (refreshing()) return false;
if (inner) return false;
refreshing(true);
final ITemplateResource templateResource = this.templateResource;
try {
RythmEngine engine = engine();
if (!templateResource.isValid()) {
// it is removed?
isValid = false;
engine.classes().remove(this);
return false;
}
ICodeType type = engine.renderSettings.codeType();
if (null == type) {
type = templateResource.codeType(engine());
}
if (null == type || ICodeType.DefImpl.RAW == type) {
type = engine.conf().defaultCodeType();
}
codeType = type;
if (null == name) {
// this is the root level template class
root = this;
name = templateResource.getSuggestedClassName() + CN_SUFFIX;
if (engine.conf().typeInferenceEnabled()) {
name += ParamTypeInferencer.uuid();
}
ITemplateResourceLoader loader = engine().resourceManager().whichLoader(templateResource);
if (null != loader) {
Object k = templateResource.getKey();
tagName = toCanonicalName(k.toString(), loader.getResourceLoaderRoot());
}
//name = templateResource.getSuggestedClassName();
engine.registerTemplateClass(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().testTemplate(tcName, this);
if (null == fullName) {
logger.warn("Unable to load included template class from name: %s", tcName);
continue;
}
TemplateClass tc = engine().getRegisteredTemplateClass(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 && !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();