String markupLanguageName,
String programmingLanguageName,
SourceResolver resolver)
throws Exception {
final Source source = resolver.resolve(fileName);
final String id = source.getSystemId();
ProgrammingLanguage programmingLanguage = null;
MarkupLanguage markupLanguage = null;
try {
// Create file name for the program generated from the provided source.
final String normalizedName = getNormalizedName(id);
// Ensure no 2 requests for the same file overlap
Program program = null;
CompiledComponent programInstance = null;
// Attempt to load program object from cache
try {
programInstance = (CompiledComponent)this.cache.select(normalizedName);
} catch (Exception e) {
getLogger().debug("The instance was not accessible from the internal cache. Proceeding.");
}
if (programInstance == null && this.preload) {
// Preloading: Load program if its source/[object file] is available
try {
markupLanguage =
(MarkupLanguage)this.markupSelector.select(markupLanguageName);
programmingLanguage =
(ProgrammingLanguage)this.languageSelector.select(programmingLanguageName);
programmingLanguage.setLanguageName(programmingLanguageName);
program = programmingLanguage.preload(normalizedName,
this.workDir, markupLanguage.getEncoding());
this.cache.addGenerator(newManager, normalizedName, program);
programInstance = (CompiledComponent)this.cache.select(normalizedName);
} catch (Exception e) {
getLogger().debug("The program was not preloaded");
}
}
/*
* FIXME: It's the program (not the instance) that must
* be queried for changes!!!
*/
if (programInstance != null && this.autoReload) {
// Autoreloading: Unload program if its source is modified
long lastModified = source.getLastModified();
if (lastModified == 0 || programInstance.modifiedSince(lastModified)) {
// Release the component.
release(programInstance);
programInstance = null;
// Unload program
if (programmingLanguage == null) {
programmingLanguage =
(ProgrammingLanguage)this.languageSelector.select(programmingLanguageName);
programmingLanguage.setLanguageName(programmingLanguageName);
}
programmingLanguage.unload(program, normalizedName, this.workDir);
this.cache.removeGenerator(normalizedName);
program = null;
}
}
// Not preloaded or just unloaded: (re)create.
if (programInstance == null) {
if (programmingLanguage == null) {
programmingLanguage =
(ProgrammingLanguage)this.languageSelector.select(programmingLanguageName);
programmingLanguage.setLanguageName(programmingLanguageName);
}
if (markupLanguage == null) {
markupLanguage =
(MarkupLanguage)this.markupSelector.select(markupLanguageName);
}
programInstance = this.createResource(newManager,
source, normalizedName, markupLanguage,
programmingLanguage, resolver);
}
// Recompose with the new manager if needed
if (programInstance instanceof Recomposable) {
((Recomposable)programInstance).recompose(newManager);
}
return programInstance;
} finally {
source.recycle();
this.markupSelector.release(markupLanguage);
this.languageSelector.release(programmingLanguage);
}
}