/*----------------------------------------------------------------------------- Copyright the original author or authors. Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (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.mozilla.org/MPL/MPL-1.1.html 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 com.bourre.data.iterator.Iterable; import com.bourre.events.EventType; import com.bourre.mvc.AbstractModel; import net.customactions.asdk.core.ICoreObject; import net.customactions.asdk.data.validator.BasicValidator; import net.customactions.asdk.data.validator.StringValidator; import net.customactions.asdk.io.file.BasicFolder; import net.customactions.asdk.io.file.File; import net.customactions.asdk.io.file.FileEvent; import net.customactions.asdk.io.file.FileListener; import net.customactions.asdk.io.file.Folder; import net.customactions.asdk.io.file.FolderEvent; import net.customactions.asdk.io.file.TextFile; import net.customactions.asdk.util.ClassUtil; import net.customactions.aslicensor.event.EngineEvent; import net.customactions.aslicensor.event.LicensorModelListener; /** * {@code LicensorModel } class is responsible of files and folder manipulation. * * <p>Use PixLib MVC Implementation * <p>Extends {@link com.bourre.mvc.AbstractModel} class * * @author Romain Ecarnot * @version 1.0 */ class net.customactions.aslicensor.mvc.LicensorModel extends AbstractModel implements FileListener, ICoreObject { //------------------------------------------------------------------------- // Events Definition //------------------------------------------------------------------------- public static var onProgressEVENT : EventType = new EventType("onProgress"); public static var onErrorEVENT : EventType = new EventType("onError"); public static var onStopEVENT : EventType = new EventType("onStop"); public static var onCompleteEVENT : EventType = new EventType("onComplete"); public static var onLicenseEVENT : EventType = new EventType("onLicense"); public static var onSelectSourceEVENT : EventType = new EventType("onSource"); public static var onListEVENT : EventType = new EventType("onList"); //------------------------------------------------------------------------- // Public API //------------------------------------------------------------------------- /** * Creates a new {@code LicensorModel} instance. */ public function LicensorModel() { super(); __oEvent = new EngineEvent(null, this); __sClassName = ClassUtil.getClassName(this); } /** * Opens and loads license file. * * <p>A {@code File} is available when {@code onOpenFileEVENT} is triggered. */ public function browseLicense(Void) : Void { var oLicenseFile : File = new TextFile(); oLicenseFile.addEventListener(FileEvent.onOpenFileEVENT, this, __onOpenLicense); oLicenseFile.load("startdir://", "Select your license file"); } /** * Opens a folder chooser dialog. * * <p>A {@code Folder} is available when {@code onSelectFolderEVENT} is triggered. */ public function browseSource(Void) : Void { __oSourceFolder = new BasicFolder(); __oSourceFolder.addEventListener(FolderEvent.onSelectFolderEVENT, this, __onSelectSource); __oSourceFolder.select("startdir://", "ActionScript source folder"); } /** * Retreives files listing in current source folder selected with {@code browseSource} method. * * <p>Listing is available throw {@code Folder.getFiles} method when {@code onListFolderEVENT} event * is triggered. */ public function check(Void) : Void { if(!BasicValidator.validate(__oSourceFolder)) { __fireEvent(onErrorEVENT, "No source folder"); return; } __oSourceFolder.addEventListener(FolderEvent.onListFolderEVENT, this, __onList); __oSourceFolder.list(); } /** * Inserts license content into all source files. * * <p>UI is disabled during process to avoid source and license modification. */ public function process(Void) : Void { __fireEvent(onProgressEVENT, "Retreives folders tree"); if(!StringValidator.validate(__oLicenseFile.getContent())) { __fireEvent(onErrorEVENT, "Invalid license file"); return; } __aFileIterator = __oSourceFolder.getIterator(); if(__aFileIterator.hasNext()) { var sFile : String = __aFileIterator.next(); var oF : File = new TextFile(); oF.addListener(this); oF.load(sFile); } else { __fireEvent(onStopEVENT, "No files found"); } } /** * Returns a {@code File} instance representing the license file. * * @return a {@code File} instance */ public function getLicenseFile(Void) : File { return __oLicenseFile; } /** * Returns a {@code Array} instance representing file listing. * * @return {@code Array} instance */ public function getSourceFiles(Void) : Array { return __oSourceFolder.getFiles(); } /** * Triggered when {@code File} instance is correctly opened. * * @param p_oEvent {@code p_oEvent} event. */ public function onOpenFile(p_oEvent : FileEvent) : Void { __openFile(p_oEvent); } /** * Triggered when {@code File} instance is correctly saved. * * @param p_oEvent {@code p_oEvent} event. */ public function onSaveFile(p_oEvent : FileEvent) : Void { __saveFile(p_oEvent); } /** * Returns full namespace + classname for this instance. * * <p>ASDK core implementation * * @return String */ public function getClassName(Void) : String { return __sClassName; } /** * {@link com.bourre.mvc.AbstractModel} overloading. * * <p>Defines specific {@code LicensorModelListener} listener type. * * @param p_oListener a {@code LicensorModelListener} instance */ public function addModelListener(p_oListener : LicensorModelListener) : Void { _oEB.addListener(p_oListener); } /*------------------------------------------------------------------------------------------*/ //------------------------------------------------------------------------- // Internal properties //------------------------------------------------------------------------- private var __sClassName : String; private var __oLicenseFile : File; private var __oEvent : EngineEvent; private var __aFileIterator : Iterable; private var __oSourceFolder : Folder; //------------------------------------------------------------------------- // Private implementation //------------------------------------------------------------------------- /** * Broadcasts event to all resgitred listener. * * <p>Use {@link com.bourre.mvc.AbstractModel.notifyChanged} method * * @param p_oEvent Event name * @param p_sMessage Message to send */ private function __fireEvent(p_oEvent : EventType, p_sMessage : String) : Void { __oEvent.setType(p_oEvent); __oEvent.setMessage(p_sMessage); notifyChanged( __oEvent ); } /** * Triggered when license file is correctly opened. * * @param p_oEvent {@code FileEvent} instance */ private function __onOpenLicense(p_oEvent : FileEvent) : Void { __oLicenseFile = p_oEvent.getFile(); __fireEvent(onLicenseEVENT, __oLicenseFile.getLocation()); } /** * Triggered when source folder is selected * * @param p_oEvent {@code FolderEvent} instance */ private function __onSelectSource(p_oEvent : FolderEvent) : Void { __oSourceFolder = p_oEvent.getFolder(); __fireEvent(onSelectSourceEVENT, __oSourceFolder.getLocation()); } /** * Triggered when Folder API correctly retreives files listing. * * @param p_oEvent {@code FolderEvent} instance */ private function __onList(p_oEvent : FolderEvent) : Void { __fireEvent(onListEVENT, __oSourceFolder.getLocation()); } /** * Opens source file and process license insertion. * * <p>If no license tags are found in source file, we iterate next * file. * * @param p_oEvent {@code FileEvent} instance * * TODO Pass boolean to force insertion if no tags found */ private function __openFile(p_oEvent : FileEvent) : Void { var oFile : File = p_oEvent.getFile(); var sContent : String = oFile.getContent(); var sChainStart : String = "/*-----------------------------------------------------------------------------"; var sChainEnd : String = "-----------------------------------------------------------------------------*/"; var aLines : Array = sContent.split("\n"); var l : Number = aLines.length; var indexStart : Number = -1; var findStart : Boolean = false; var indexEnd : Number = -1; var findEnd : Boolean = false; for(var i : Number = 0; i < l; i++) { if(aLines[i] == sChainStart) { indexStart = i; findStart = true; } if(aLines[i] == sChainEnd) { if(findStart) { indexEnd = i; findEnd = true; break; } } } if(findStart && findEnd) { var n : Number = indexEnd - indexStart; for(var j : Number = 0; j < n; j++) { aLines.shift(); } var aLicense : Array = __oLicenseFile.getContent().split("\n"); var ll : Number = aLicense.length; while(--ll > -1) { aLines.unshift(aLicense[ll]); } aLines.unshift(sChainStart); oFile.setContent(aLines.join("\n")); oFile.save(); } else { __next(); } } /** * Unregisters current source file, and iterate next. */ private function __saveFile(p_oEvent : FileEvent) : Void { p_oEvent.getFile().removeListener(this); __next(); } /** * Iterate next */ private function __next(Void) : Void { if(__aFileIterator.hasNext()) { var sFile : String = __aFileIterator.next(); var oF : File = new TextFile(); oF.addListener(this); oF.load(sFile); } else { __fireEvent(onCompleteEVENT, "Licensing successfully"); } } }