jec-sandcat
Version:
JEC Sandcat - The default RESTful web services framework for GlassCat applications.
237 lines (212 loc) • 8.3 kB
text/typescript
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
//
// Copyright 2016-2018 Pascal ECHEMANN.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {DomainConnector} from "jec-glasscat-core";
import {JsletContext} from "jec-exchange";
import {ResourceProxyJsletFactory} from "./ResourceProxyJsletFactory";
import {RootPathDescriptorFactory} from "./RootPathDescriptorFactory";
import {ResourceJsletProxy} from "../jslet/ResourceJsletProxy";
import {Sandcat} from "../Sandcat";
import {SandcatLoggerProxy} from "../logging/SandcatLoggerProxy";
import {LoggerProxy, FilePreProcessor, FileProperties, DecoratorProperties, LogLevel} from "jec-commons";
import {RootPathDescriptor} from "../reflect/RootPathDescriptor";
import {JarsContextManager} from "../jcad/JarsContextManager";
import {SandcatError} from "../exceptions/SandcatError";
import {SandcatLocaleManager} from "../i18n/SandcatLocaleManager";
import {LocaleManager} from "jec-commons-node";
/**
* The <code>SandcatAutowireProcessor</code> class allows to find all Sandcat
* resources of an <code>EjpContainer</code> instance.
*/
export class SandcatAutowireProcessor implements FilePreProcessor {
////////////////////////////////////////////////////////////////////////////
// Constructor function
////////////////////////////////////////////////////////////////////////////
/**
* Creates a new <code>SandcatAutowireProcessor</code> instance.
*/
constructor() {
this.initObj();
}
////////////////////////////////////////////////////////////////////////////
// Private properties
////////////////////////////////////////////////////////////////////////////
/**
* The mask used to detect the <code>jec-jars</code> imports in a file.
*/
private static readonly JARS_MASK:string = "jec-jars";
/**
* The mask used to detect the <code>@ResourcePath</code> decorator in a file.
*
*/
private static readonly RESOURCE_MASK:string = "ResourcePath";
/**
* The mask used to detect the <code>@RootPath</code> decorator in a file.
*/
private static readonly API_MASK:string = "RootPath";
/**
* The collection of <code>FileProperties</code> instances that represent a
* resource.
*/
private _resourceFiles:FileProperties[] = null;
/**
* The collection of <code>FileProperties</code> instances that represent a
* root path.
*/
private _rootPathFiles:FileProperties[] = null;
/**
* The reference to the Sandcat container that runs this processor.
*/
private _sandcatContainer:Sandcat = null;
/**
* The reference to the <code>JarsContextManager</code> that is used to manage
* JCAD context objects for this processor.
*/
private _contextManager:JarsContextManager = null;
////////////////////////////////////////////////////////////////////////////
// Private methods
////////////////////////////////////////////////////////////////////////////
/**
* Initializes this object.
*/
private initObj():void {
this._resourceFiles = new Array<FileProperties>();
this._rootPathFiles = new Array<FileProperties>();
this._contextManager = new JarsContextManager();
this._contextManager.createContext();
}
/**
* Apply file pre-processing transformations to the <code>@Resource</code>
* annotated files.
*
* @param {DomainConnector} connector the domain connector for which file
* pre-processing is performed.
*/
private transformResourceFiles(connector:DomainConnector):void {
const context:JsletContext = connector.getContainer().getJsletContext();
const contextRoot:string = connector.getContextRoot();
const resources:string[] = new Array<string>();
const factory:ResourceProxyJsletFactory = new ResourceProxyJsletFactory();
let len:number = this._resourceFiles.length;
let jslet:ResourceJsletProxy = null;
while(len--) {
jslet = factory.create(
this._resourceFiles[len], contextRoot, this._sandcatContainer
);
context.addJslet(jslet);
}
this._resourceFiles.splice(0);
}
/**
* Apply file pre-processing transformations to the <code>@RootPath</code>
* annotated files.
*/
private transformRootPathFiles():void {
const rootPaths:string[] = new Array<string>();
const factory:RootPathDescriptorFactory = new RootPathDescriptorFactory();
let len:number = this._rootPathFiles.length;
let rootPath:RootPathDescriptor = null;
while(len--) {
rootPath = factory.create(this._rootPathFiles[len]);
this._sandcatContainer.addRootPath(rootPath);
}
this._rootPathFiles.splice(0);
}
/**
* Throws a <code>SandcatError</code> exception whether the
* <code>processCompleteHandler</code> property is <code>null</code>.
*/
private validateCallbackHandler():void {
if(!this.processCompleteHandler) {
throw new SandcatError(
SandcatLocaleManager.getInstance().get("errors.processor")
);
}
}
////////////////////////////////////////////////////////////////////////////
// Public properties
////////////////////////////////////////////////////////////////////////////
/**
* A callback method called when the <code>processComplete()</code> method is
* invoked. This property must not be <code>null</code> when the
* <code>processStart()</code> and <code>processComplete()</code> method are
* invoked.
*/
public processCompleteHandler:Function = null;
////////////////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////////////////
/**
* Sets the Sandcat container reference for this processor.
*
* @param {Sandcat} container the reference to the Sandcat container for this
* processor.
*/
public setSandcatContainer(container:Sandcat):void {
this._sandcatContainer = container;
}
/**
* Sets the Sandcat container reference for this processor.
*
* @return {Sandcat} the reference to the Sandcat container for this
* processor.
*/
public getSandcatContainer():Sandcat {
return this._sandcatContainer;
}
/**
* @inheritDoc
*/
public processStart(watcher:any, sourcePath:string):void {
this.validateCallbackHandler();
}
/**
* @inheritDoc
*/
public process(file:FileProperties, connector:DomainConnector):void {
const decorators:DecoratorProperties[] = file.decorators;
const logger:LoggerProxy = SandcatLoggerProxy.getInstance();
const i18n:LocaleManager = SandcatLocaleManager.getInstance();
const fileName:string = file.name;
let len:number = decorators.length;
let decorator:DecoratorProperties = null;
let classPath:string = null;
let decoratorName:string = null;
while(len--) {
decorator = decorators[len];
classPath = decorator.classPath;
decoratorName = decorator.name;
if(classPath === SandcatAutowireProcessor.JARS_MASK) {
if(decoratorName === SandcatAutowireProcessor.RESOURCE_MASK) {
this._resourceFiles.push(file);
logger.log(i18n.get("autowire.resource", fileName), LogLevel.DEBUG);
} else if(decoratorName === SandcatAutowireProcessor.API_MASK) {
this._rootPathFiles.push(file);
logger.log(i18n.get("autowire.version", fileName), LogLevel.DEBUG);
}
}
}
}
/**
* @inheritDoc
*/
public processComplete(connector:DomainConnector, sourcePath:string) {
this.validateCallbackHandler();
this.transformRootPathFiles();
this.transformResourceFiles(connector);
this._contextManager.deleteContext();
this.processCompleteHandler();
}
}