CFDJ Vol. 3 , Issue 1 - pg.42
Building Fusebox Frameworks Visually, by Jeff Peters

001 <!-- FuseMinder.cfm by jeff.peters@bigfoot.com -->
002
003 <!---
004 || FUSEDOC ||
005
006 || General ||
007 Name: FuseMinder.cfm (formerly MindReader)
008 Author: jeff.peters@bigfoot.com
009
010 || Responsibilities ||
011 I read a text outline file of the form generated by Visual Mind and generate the
012 specified circuit apps, including fuseboxes and fusestubs.
013 If "attributes.location" is not defined, I use the current directory as home.
014 If "attributes.verbose" is TRUE or not defined, I produce progress statements
015 while working.  If "attributes.indenter" is not defined, I use two spaces ("  ")
016 as the outline indenting string.
017
018 || Attributes ||
019 --> attributes.outlineFile: a STRING ( name of outline file )+
020 --> attributes.location: a STRING ( location of outline file )
021 --> attributes.verbose: a BOOLEAN ( FALSE )
022 --> attributes.indenter: a STRING ( string to use for indenting outline levels )
023
024 || END FUSEDOC ||--->
025 <cfparam name="attributes.OutlineFile" default="DACF.txt">
026 <cfparam name="attributes.verbose" default="True">
027 <cfparam name="attributes.location" default="#GetDirectoryFromPath(GetCurrentTemplatePath())#">
028 <cfparam name="attributes.indenter" default="  ">
029
030 <cfif attributes.verbose EQ "Yes">
031 FuseMinder v 1.0 by jeff.peters@bigfoot.com - rundate:<cfoutput>#Dateformat(Now())#, #TimeFormat(Now())#</cfoutput>
032 <hr>
033 </cfif>
034
035 <cfif IsDefined("attributes.OutlineFile") EQ "No">
036   <cfthrow type="MindReaderError" message="OutlineFile not specified.">
037 </cfif>
038
039 <cfset homeRoot = "#attributes.location#">
040
041 <cfset Crlf = "#Chr(10)#">
042 <!--- If homeRoot has a colon in it, we're in Windows, else Unix --->
043 <cfif Find(":",homeRoot) GT 0>
044   <cfset slash = "\">
045 <cfelse>
046   <cfset slash = "/">
047 </cfif>
048
049 <cfset lastType = "">
050 <cfset lastCircuit = "">
051 <cfset lastFuseaction = "">
052 <cfset fbOpenLines = "<cfswitch expression='fuseaction'>#Crlf#">
053 <cfset modeEverybodyReadWrite = 666>
054
055 <!--- Indenting string constants --->
056 <cfset indenterCircuit = RepeatString(#attributes.indenter#,1)>
057 <cfset indenterFuseaction = RepeatString(#attributes.indenter#,2)>
058 <cfset indenterFuse = RepeatString(#attributes.indenter#,3)>
059 <cfset indenterFusedoc = RepeatString(#attributes.indenter#,4)>
060
061 <!--- Home fusebox string constants --->
062 <cfset hfbOpenLines = "<cfswitch expression='##ListFirst(fuseaction,'.')##'>">
063 <cfset hfbCloseLines = "  <cfdefaultcase>#Crlf#    No handler for this fuseaction.#Crlf#  </cfdefaultcase>#Crlf#</cfswitch>">
064
065 <!--- Fusebox file string constants --->
066 <cfset fbOpenLines = "<cfswitch expression='##ListLast(fuseaction,'.')##'>">
067 <cfset fbCloseLines = "  </cfcase>#Crlf#  <cfdefaultcase>#Crlf#    No handler for this fuseaction.#Crlf#  </cfdefaultcase>#Crlf#</cfswitch>">
068 <cfset fbOpenCaseStart = "  <cfcase value='">
069 <cfset fbOpenCaseEnd = "'>">
070 <cfset fbIncludeStart = "    <cfinclude template='">
071 <cfset fbIncludeEnd = "'>">
072 <cfset fbCloseCase = "  </cfcase>">
073
074 <!--- Fuse file string constants --->
075 <cfset ffNoteLineStart = "<!--- ">
076 <cfset ffNoteLineEnd = " --->">
077 <cfset ffAuthor = "">
078
079 <cfset aryCircuitNames = ArrayNew(1)>
080
081 <!--- Read in text file, ignoring header info --->
082 <cffile action="read" variable="strRawInput" file="#homeRoot##attributes.OutlineFile#">
083 <cfset aryOutline = ListToArray(strRawInput,Crlf)>
084
085 <!--- For each line in spec: --->
086 <cfloop from="1" to="#ArrayLen(aryOutline)#" index="lineNum">
087  <!--- Determine line type based on number of leading spaces --->
088  <cfif Left(aryOutline[lineNum],8) EQ "#indenterFusedoc#">
089    <cfset lineType = "fusedoc">
090  <cfelseif Left(aryOutline[lineNum],6) EQ "#indenterFuse#">
091    <cfset lineType = "fuse">
092  <cfelseif Left(aryOutline[lineNum],4) EQ "#indenterFuseaction#">
093    <cfset lineType = "fuseaction">
094  <cfelseif Left(aryOutline[lineNum],2) EQ "#indenterCircuit#">
095    <cfset lineType = "circuit">
096  <cfelseif Left(aryOutline[lineNum],2) GT "#indenterCircuit#">
097    <cfset lineType = "homeapp">
098  <cfelse>
099    <cfset lineType = "unknown">
100  </cfif>
101
102  <CFSWITCH expression="#lineType#">
103      <cfcase value="homeapp">
104           <!--- Store name of home app --->
105     <cfset appLine = Trim(aryOutline[lineNum])>
106     <cfset appName = Trim(ListFirst(appLine,":"))>
107     <cfif FindNoCase(":",appLine) GT 0>
108       <cfset ffAuthor = " by #ListLast(appLine,":")#">
109     </cfif>
110     <cfif attributes.verbose EQ "Yes">
111       <cfoutput>Building files for #appName##ffAuthor#.<br></cfoutput>
112     </cfif>
113   </cfcase>
114
115   <cfcase value="circuit">
116     <cfset circuitIndex = ArrayLen(aryCircuitNames) + 1>
117     <!--- aryCircuitNames will be used to build the home fusebox at the end. --->
118           <cfset circuitName = "#Trim(ListLast(aryOutline[lineNum],indenterCircuit))#">
119     <cfset aryCircuitNames[circuitIndex] = circuitName>
120     <cfset circuitPath="#homeRoot##circuitName#">
121
122     <!--- If lastCircuit is not this circuit name and not empty, write
123        closing lines to last circuit's fusebox.--->
124     <cfif (lastCircuit GT "") AND (lastCircuit NEQ "#circuitName#")>
125
126       <cffile action="APPEND"
127              file="#homeRoot##lastCircuit##slash#index.cfm"
128            output="#fbCloseLines#">
129    <cfset circuitClosed = "Yes">
130    <cfset lastCircuit = "#circuitName#">
131     </cfif>
132           <!--- Create the circuit directory; ignore error if it already exists. --->
133     <cfset circuitClosed = "No">
134     <cftry>
135             <cfdirectory action="create"
136              directory="#circuitPath#">
137    <cfcatch type="Any">
138    </cfcatch>
139     </cftry>
140     <!--- Create index.cfm for circuit and write opening lines --->
141     <cftry>
142       <cffile action="read" file="#circuitPath##slash#index.cfm" variable="foo">
143    <cfcatch type="Any">
144      <!--- Write note line (first line of file) to fusebox file --->
145      <cffile action="WRITE"
146                mode="#modeEverybodyReadWrite#"
147                      file="#circuitPath##slash#index.cfm"
148           output="#ffNoteLineStart#index.cfm for #circuitName# circuit#ffAuthor##ffNoteLineEnd#">
149      <cffile action="APPEND"
150                    file="#circuitPath##slash#index.cfm"
151                 output="#fbOpenLines#">
152    </cfcatch>
153        </cftry>
154   <cfif attributes.verbose EQ "Yes">
155     <cfoutput>Building #circuitName# circuit.<br></cfoutput>
156   </cfif>
157   </cfcase>
158
159   <cfcase value="fuseaction">
160     <cfset fuseactionName = "#Trim(ListLast(aryOutline[lineNum],indenterFuseaction))#">
161     <!--- If lastFuseaction is not this fuseaction name and not empty, write
162        case closing lines to appropriate circuit's fusebox.--->
163     <cfif ((lastFuseaction NEQ "") AND (lastFuseaction NEQ fuseactionName))>
164      <cfif ((lastCircuit NEQ "") AND (lastCircuit NEQ circuitName))>
165        <cffile action="APPEND"
166               file="#homeRoot##lastCircuit##slash#index.cfm"
167             output="#fbCloseCase#">
168      <cfelse>
169        <cfif lastType NEQ "circuit">
170         <cffile action="APPEND"
171                file="#circuitPath##slash#index.cfm"
172              output="#fbCloseCase#">
173     </cfif>
174      </cfif>
175      <cfset lastCircuit = "#circuitName#">
176     </cfif>
177     <!--- Append fuseaction's cfcase line to current circuit's fusebox --->
178     <cffile action="APPEND"
179                     file="#circuitPath##slash#index.cfm"
180          output="#fbOpenCaseStart##fuseactionName##fbOpenCaseEnd#">
181     <!--- Set lastFuseaction = fusecactionName --->
182     <cfset lastFuseaction = "#fuseactionName#">
183     <cfif attributes.verbose EQ "Yes">
184       <cfoutput>&nbsp;&nbsp;Fuseaction #fuseactionName# written.<br></cfoutput>
185     </cfif>
186   </cfcase>
187
188   <cfcase value="fuse">
189     <cfset fuseFile = "#Trim(ListLast(aryOutline[lineNum],indenterFuse))#">
190     <!--- Append cfinclude line to fusebox for lastCircuit --->
191     <cffile action="APPEND"
192                     file="#circuitPath##slash#index.cfm"
193          output="#fbIncludeStart##fuseFile##fbIncludeEnd#">
194     <!--- Write note line (first line of file) to fuse file --->
195     <cffile action="WRITE"
196               mode="#modeEverybodyReadWrite#"
197                     file="#circuitPath##slash##fuseFile#"
198          output="#ffNoteLineStart##fuseFile##ffAuthor##ffNoteLineEnd#">
199        <cfif attributes.verbose EQ "Yes">
200             <cfoutput>&nbsp;&nbsp;&nbsp;&nbsp;Fuseaction #fuseFile# written.<br></cfoutput>
201     </cfif>
202   </cfcase>
203
204   <cfcase value="fusedoc">
205     <!--- Append fusedoc line to fuseFile --->
206     <cffile action="APPEND"
207                     file="#circuitPath##slash##fuseFile#"
208          output="#Trim(ListLast(aryOutline[lineNum],indenterFuse))#">
209   </cfcase>
210   <cfdefaultcase>
211   </cfdefaultcase>
212  </cfswitch>
213  <cfset lastType=lineType>
214 </cfloop>
215
216 <!-- If the last circuit wasn't closed, write closing lines to its file. -->
217 <cfif circuitClosed EQ "No">
218   <cffile action="APPEND"
219          file="#circuitPath##slash#index.cfm"
220        output="#fbCloseLines#">
221 </cfif>
222
223 <!-- Now write the home app's fusebox file --->
224 <!--- Write opening lines --->
225 <cftry>
226   <cffile action="read" file="#homeRoot#index.cfm" variable="foo">
227 <cfcatch type="Any">
228   <!--- Write note line (first line of file) to fusebox file --->
229   <cffile action="WRITE"
230             mode="#modeEverybodyReadWrite#"
231             file="#homeRoot#index.cfm"
232        output="#ffNoteLineStart#index.cfm for #appName# application#ffAuthor##ffNoteLineEnd#">
233   <cffile action="APPEND"
234             file="#homeRoot#index.cfm"
235           output="#hfbOpenLines#">
236 </cfcatch>
237 </cftry>
238 <!--- Write each case --->
239 <cfloop from="1" to="#ArrayLen(aryCircuitNames)#" index="i">
240   <!--- Append circuit's cfcase lines to current circuit's fusebox --->
241   <cffile action="APPEND"
242             file="#homeRoot#index.cfm"
243        output="#fbOpenCaseStart##Left(aryCircuitNames[i],4)##fbOpenCaseEnd#">
244
245   <cffile action="APPEND"
246             file="#homeRoot#index.cfm"  output="#fbIncludeStart##aryCircuitNames[i]##slash#index.cfm?fuseaction=##fuseaction###fbIncludeEnd#">
247
248   <cffile action="APPEND"
249             file="#homeRoot#index.cfm"
250           output="#fbCloseCase#">
251 </cfloop>
252 <!--- Write closing lines --->
253 <cffile action="APPEND"
254           file="#homeRoot#index.cfm"
255         output="#hfbCloseLines#">
256
257 <cfif attributes.verbose EQ "Yes">
258   <cfoutput>Fusebox file for #appName# application written.</cfoutput>
259 </cfif>
260
261 <!-- Output end of process message --->
262 <cfif attributes.verbose EQ "Yes">
263   <cfoutput>Application build complete.<br></cfoutput>
264   <hr>
265   &copy; 2000 All Rights Reserved
266 </cfif>