0

AOP ROCKS

Building The Blog

I 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

 

Sam Clement said:
 
Great post! I've been wanting to check out AOP in Coldspring for a long time.

Would it be possible to see the validation.cfc? I just want to see what happens when the validation component validates (or not)... How does the application know what to do next, based on the validation result?

 
posted 884 days ago
Add Comment Reply to: this comment OR this thread
 

Search