jec-sandcat
Version:
JEC Sandcat - The default RESTful web services framework for GlassCat applications.
234 lines (217 loc) • 9.06 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 {ResourceDescriptor} from "../reflect/ResourceDescriptor";
import {MethodDescriptor} from "../reflect/MethodDescriptor";
import {ParameterDescriptor} from "../reflect/ParameterDescriptor";
import {UrlStringsEnum, LogLevel} from "jec-commons";
import {ParametersMapUtil} from "../utils/ParametersMapUtil";
import {Sandcat} from "../Sandcat";
import {RootPathDescriptor} from "../reflect/RootPathDescriptor";
import {SandcatLoggerProxy} from "../logging/SandcatLoggerProxy";
import {SandcatLocaleManager} from "../i18n/SandcatLocaleManager";
/**
* A helper class that decorates a jslet by adding it
* <code>ResourceDescriptor</code> capabilities.
*/
export class ResourceDescriptorUtil {
//////////////////////////////////////////////////////////////////////////////
// Constructor function
//////////////////////////////////////////////////////////////////////////////
/**
* Creates a new <code>RequestProperties</code> instance.
*
* @param {any} resource the resource object to decorate.
* @param {ResourceDescriptor} descriptor the <code>ResourceDescriptor</code>
* object associated with the specified
* resource object to decorate.
* @param {Sandcat} sandcatContainer the sandcat container associated with
* the specified resource object to
* decorate.
*/
constructor(resource:any, descriptor:ResourceDescriptor,
sandcatContainer:Sandcat) {
this.initObj(resource, descriptor, sandcatContainer);
}
//////////////////////////////////////////////////////////////////////////////
// Private properties
//////////////////////////////////////////////////////////////////////////////
/**
* The resource object decorated by this utility class.
*/
private _resource:any = null;
/**
* The <code>ResourceDescriptor</code> associated with the specified resource
* object to decorate.
*/
private _descriptor:ResourceDescriptor = null;
/**
* The liste of URL patterns associated with the specified resource object to
* decorate. URL patterns are computed from the root path objects associated
* with the resource object.
*/
private _urlPatterns:string[];
//////////////////////////////////////////////////////////////////////////////
// Private methods
//////////////////////////////////////////////////////////////////////////////
/**
* Initializes this object.
*
* @param {any} resource the resource object to decorate.
* @param {ResourceDescriptor} descriptor the <code>ResourceDescriptor</code>
* object associated with the specified
* resource object to decorate.
* @param {Sandcat} sandcatContainer the sandcat container associated with
* the specified resource object to
* decorate.
*/
private initObj(resource:any, descriptor:ResourceDescriptor,
sandcatContainer:Sandcat):void {
this._resource = resource;
this._descriptor = descriptor;
this.initUrlPatterns(sandcatContainer);
}
/**
* Fixes all parameter properties for the specified
* <code>MethodDescriptor</code> object.
*
* @param {MethodDescriptor} descriptor the <code>MethodDescriptor</code>
* object for which to fix all parameter
* values.
*/
private fixParameterMethodDescriptors(descriptor:MethodDescriptor):void {
const paramDescColl:ParameterDescriptor[] =
ParametersMapUtil.getParameterCollection(descriptor.name);
const paramNamesColl:string[] = descriptor.parameterNames;
let len:number = paramDescColl.length;
let paramDesc:ParameterDescriptor = null;
let paramName:string = null;
while(len--) {
paramDesc = paramDescColl[len];
paramName = paramNamesColl[paramDesc.index];
paramDesc.key = paramName;
descriptor.parametersMap.set(paramName, paramDesc);
}
}
/**
* Initializes the URL patterns of resource object to decorate, by using the
* context root specified by the sandcat container.
*
* @param {Sandcat} sandcatContainer the sandcat container associated with
* the specified resource object to
* decorate.
*/
private initUrlPatterns(sandcatContainer:Sandcat):void {
const resourcePath:string = this._descriptor.resourcePath;
const descriptorPatterns:Array<string> = new Array<string>();
const rootPathRefs:string[] = this._descriptor.rootPathRefs;
let len:number = -1;
let rootPathRef:string = null;
let rootPathDescriptor:RootPathDescriptor = null;
this._urlPatterns = new Array<string>();
if(rootPathRefs) {
len = rootPathRefs.length;
while(len--) {
rootPathRef = rootPathRefs[len];
rootPathDescriptor = sandcatContainer.getRootPath(rootPathRef);
if(rootPathDescriptor) {
this._urlPatterns.push(rootPathDescriptor.fullPath + resourcePath);
}
}
} else {
this._urlPatterns.push(resourcePath);
}
len = this._urlPatterns.length;
if(len === 0) {
SandcatLoggerProxy.getInstance().log(
SandcatLocaleManager.getInstance().get(
"mapping.missing", this._descriptor.resourcePath
),
LogLevel.WARN
);
} else {
while(len--) {
rootPathRef = this._urlPatterns[len];
descriptorPatterns.push(rootPathRef + UrlStringsEnum.PERM_MARK);
}
}
this._descriptor.urlPatterns = descriptorPatterns;
}
/**
* Sets the URL patterns of the specified method descriptor.
*
* @param {string} contextRoot the context root property of the container
* that contains the resource to decorate.
* @param {MethodDescriptor} desc the method descriptor for which to set the
* URL patterns.
*/
private setMethodUrlPatterns(contextRoot:string, desc:MethodDescriptor):void {
const urlPatterns:string[] = new Array<string>();
let len:number = this._urlPatterns.length;
let rootPathPattern:string = null;
let pattern:string = null;
while(len--){
rootPathPattern = contextRoot + this._urlPatterns[len];
pattern = rootPathPattern + (desc.route || UrlStringsEnum.EMPTY_STRING);
urlPatterns.push(pattern);
}
desc.urlPatterns = urlPatterns;
}
//////////////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////////////
/**
* Adds <code>MethodDescriptor</code> capabilities to the specified resource
* object.
*/
public decorate():void {
const resource:any = this._resource;
Object.defineProperty(
resource,
"__sandcatResourceDescriptor",
{
enumerable: false,
configurable: false,
value: this._descriptor
}
);
Object.defineProperty(
resource,
"getResourceDescriptor",
{
enumerable: false,
configurable: false,
writable: false,
value: function():ResourceDescriptor {
return resource.__sandcatResourceDescriptor;
}
}
);
}
/**
* Fixes the all of the composite values for the <code>MethodDescriptor</code>
* object associated with the decorated resource object.
*/
public fixCompositeValues():void {
const contextRoot:string = UrlStringsEnum.SLASH +
this._descriptor.contextRoot;
this._descriptor.methodsMap.forEach(
(desc:MethodDescriptor, key:string, map:Map<string, MethodDescriptor>)=> {
this.setMethodUrlPatterns(contextRoot, desc);
this.fixParameterMethodDescriptors(desc);
}
);
}
};