AOP ROCKS
Building The BlogI was at the point to adding Validation to my Model tBLog engine, a transposition of Mark Mandel's tBlog example application to Model Glue Unity.
ARG, I don't want to muck up controller or model code with Validation! Where the heck will it go cleanly? Example of updatePost:
ModelGlue.xml:
<!--
updatePost
Description: I submit the frmPost.cfm form
-->
<event-handler name="updatePost">
<broadcasts>
<message name="checkUserLogin" />
<message name="updatePost" />
</broadcasts>
<results>
<result do="listPosts" />
</results>
</event-handler>
BlogController.cfc (Front controller for HTML requests):
<!--- updatePost --->
<cffunction name="updatePost" hint="I ask the model to save / update a Post." access="public" returnType="any" output="false">
<cfargument name="event" type="any" />
<!--- get the values from the framework --->
<cfset var ID = arguments.event.getValue("ID") />
<cfset var Title = arguments.event.getValue("Title") />
<cfset var body = arguments.event.getValue("body") />
<cfset var PostFile = arguments.event.getValue("PostFile") />
<cfset var VideoFile = arguments.event.getValue("VideoFile") />
<cfset var Category = arguments.event.getValue("Category") />
<cfset var User = arguments.event.getValue("User") />
<cfset var IDComment = arguments.event.getValue("IDComment") />
<!--- ask the model to update the Post --->
<cfset var updatePost = variables.BlogService.updatePost(ID, Title, body, PostFile, VideoFile, Category, User, IDComment) />
<cfreturn arguments.event />
</cffunction>
BlogService.cfc (service layer to react to requests, HTML front controller or remote requests):
<!--- updatePost --->
<cffunction name="updatePost" hint="I ask Transfer to update a post." access="public" displayname="Save Post" returntype="any" output="false">
<cfargument name="ID" hint="I am the ID of the Post that is being updated.<br />I am required.">
<cfargument name="Title" hint="I am the Title of the post.<br />I am required.">
<cfargument name="body" hint="I am the body of the post.<br />I am required.">
<cfargument name="PostFile" hint="I am the PostFile of the post.">
<cfargument name="VideoFile" hint="I am the VideoFile of the post.">
<cfargument name="Category" hint="I am the list of Catagories of the post.<br />I am required.">
<cfargument name="User" hint="I am the User who posted the post.<br />I am required.">
<cfargument name="IDComment" hint="I am the list of comments that will be deleted.<br />I am required.">
<!--- get the post --->
<cfset var post = variables.transfer.get("post.Post", arguments.ID) />
<!--- make and array of the incomming category ID's --->
<cfset var categories = listToArray(arguments.category)>
<cfset var len = ArrayLen(categories) />
<cfset var PostFileName = "" />
<cfset var VideoFileName = "" />
<!--- check if there is a file --->
<cfif len(arguments.PostFile)>
<cfset PostFileName = variables.FileService.uploadPostFile(arguments.PostFile) />
<!--- set the PostFileName --->
<cfset post.setPostFileName(PostFileName) />
</cfif>
<!--- check if there is a video --->
<cfif len(arguments.VideoFile)>
<cfset VideoFileName = variables.FileService.uploadVideo(arguments.VideoFile) />
<!--- set the VideoFileName --->
<cfset post.setVideoFileName(VideoFileName) />
</cfif>
<!--- set the title and body --->
<cfset post.setTitle(arguments.title) />
<cfset post.setBody(arguments.Body) />
<!--- set the user --->
<cfset post.setUser(variables.transfer.get("user.User", arguments.user)) />
<!--- clear out the categories --->
<cfset post.clearCategory() />
<!--- loop through the categories and add them back in --->
<cfloop from="1" to="#len#" index="counter">
<cfset category = variables.transfer.get("system.Category", categories[counter]) />
<cfset post.addCategory(category) />
</cfloop>
<!--- do sorting afterwould to make sure they are in the right order --->
<cfset post.sortCategory() />
<!--- delete the comments that are selected --->
<cfif (StructKeyExists(arguments, "IDComment"))>
<cfset IDComments = listToArray(arguments.IDComment) />
<cfset len = ArrayLen(IDComments) />
<cfloop from="1" to="#len#" index="counter">
<cfset comment = transfer.get("post.Comment", IDComments[counter]) />
<!--- comment is removed implicitely from Post on delete --->
<cfset x = transfer.delete(comment) />
</cfloop>
</cfif>
<!--- save the Post --->
<cfset x = transfer.save(post) />
</cffunction>
FileService.cfc called by BlogService.cfc(updatePost)
<!--- uploadPostFile --->
<cffunction name="uploadPostFile" hint="I upload a file to the public file directroy. I then then retrun the name." displayname="Upload Post File" access="public" returntype="any" output="false">
<cfargument name="PostFileName" hint="I am the file being uploaded.<br />I am required." />
<!--- upload the single file --->
<cffile
action="upload"
destination = "#ExpandPath('/com/blog/views/public/uploads/posts/')#"
nameconflict="overwrite"
filefield="PostFile" />
<!--- get the file name --->
<cfset PostFileName = (#cffile.SERVERFILE#)>
<cfreturn PostFileName />
</cffunction>
<!--- uploadVideo --->
<cffunction name="uploadVideo" hint="I parse a video into flash with FFMPEG (Google: FFMPEG), I then place the flash file into the public video directroy. I then put the uploaed video into the 'origionalvideo' folder at the COM level." displayname="Upload Video" access="public" returntype="any"output="false">
<cfargument name="VideoFile" hint="I am the video being uploaded.<br />I am required." />
<!--- upload the video to the a directory at the COM level --->
<cffile
action="upload"
destination = "#ExpandPath('/origionalvideo/')#"
nameconflict="overwrite"
filefield="VideoFile" />
<!--- convert the video with FFMPEG --->
<cfexecute name = "#ExpandPath('/')#ffmpeg.exe"
arguments = "-i #ExpandPath('/origionalvideo/')##cffile.SERVERFILE# -s 320x240 -r 15 -b 2000 -ar 44100 -ab 64 -ac 2 #ExpandPath('/com/blog/views/public/uploads/video/')##replace(cffile.SERVERFILE, ".", "")#.flv"
outputFile = "C:\"
timeout = "90000000">
</cfexecute>
<!--- create the file name --->
<cfset VideoFileName = "#replace(cffile.SERVERFILE, ".", "")#.flv" />
<cfreturn VideoFileName />
</cffunction>
Now if anyone can tell me where a logical place to put Security or Validation is please?
ColdSpring AOP HOW I LOVE THEE:
<!--
Desicription: I am called by ColdSpring BEFORE the BlogService.cfc.
I take the request and pass the data to the Validaiton.cfc.
Validation.cfc checks:
1. There is a title
2. There is a category
3. video is a .avi, .mpg, .mov, or .wmv.
-->
<bean id="ValidationAdvisor"
class="coldspring.aop.support.NamedMethodPointcutAdvisor">
<property name="advice">
<ref bean="Validation" />
</property>
<property name="mappedNames">
<value>updatePost</value>
</property>
</bean>
<!-- the Validatoin.cfc called by ValidationAdvisor --->
<bean id="Validation" class="&applicationMapping;aspects.Validation" singleton="true" autowire="byName" />
<!-- I am the Proxy for the BlogService.cfc. See the TargetBlogService bean below. -->
<bean id="BlogService"
class="coldspring.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="TargetBlogService" />
</property>
<property name="interceptorNames">
<list>
<value>securityAdvisor</value>
</list>
</property>
</bean>
<!-- BlogService PROXIED BY COLDSPRING -->
<bean id="TargetBlogService" class="&applicationMapping;model.BlogService" singleton="true" autowire="byName" />
I am consuming my addPost incoming request with the ColdSpring framework
My core blog code dose not change! HAPPY ME HAPPY ME!
Thanks Dave Ross! ColdSpring's AOP ROCKS





Loading....