July 31, 2004
Architecture
A sound architectural plan will make an IT strategy, but without an IT strategy there really isn’t anyway to have an architectural plan. With the right architectural strategy, health care organizations can roll out new apps faster, and reduce maintenance costs, by having standardized structures in place. Architectural evaluation and strategizing for the future state is not really for the weak of heart. First, it is a good idea to understand what the current state of application architecture. In exhaustive detail, list all of the applications, interfaces, and processes. Include the language, vendor, platform, database engine, last release, last update for application. For interfaces include the transport mechanism, whether it is realtime or batch, if there is a standardized transaction format, the trigger mechanism, if it is manual. Have a process guide that links all of the steps together to get from the starting point to the ending point. Next figure out where you want to go, and develop a sound architectural team that will help you get there. Develop a bridge strategy, with a couple of quick wins that will help the outcome. Architecture encompasses a design of the infrastructure and policies on how to build and maintain the infrastructure. There are policies on technology standards, security standards, usability standards, change management standards, operations standards, and mechanisms for evaluating and exploiting new technologies. The goal of a good architectural strategy is to reduce complexity and cost, and make the most of what one has in house.
XQuery API for Java (XQJ)
XQuery API for Java(XQJ) is in early specification draft review. Currently there isn't an API that allows for the querying of XML data within the sun j2ee. This JSR proposes allowing applications to submit XQuery queries to an XML data source and then perform operations on the result of these queries.
The JSR is supported by several big hitters: BEA Systems, DataDirect Technologies, IBM, Oracle, Sun Microsystems, Sybase, and X-Hive.
How to install ASP.Net
ASP.Net runs from within IIS, I'm going to assume that IIS is already installed and configured. First, check to see if you already have the .NET Framework installed. The easiest was to do this is to look in add/remove programs for the Microsoft .NET Framework 1.1
Go to the location where the Framework is installed, probably located at C:\WINDOWS\Microsoft.NET\Framework. You will find your version of .NET, mine was v1.1.4322. If you don't have it installed, you can download it from here.
At the dos prompt run
%windir%\Microsoft.NET\Framework\ v1.1.4322\aspnet_regiis.exe -i
regsvr32 %windir%\Microsoft.NET\Framework\ v1.1.4322\aspnet_isapi.dll
(use the framework version you have, remember that mine was v1.1.4322)
Now create a test page. I called mine, time.aspx.
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="iso-8859-1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
</head>
<body>
<h1>hello it is <% Response.Write(DateTime.Now.ToString()); %></h1>
</body>
</html>
And test it out by runing http://localhost/time.aspx
Viola .NET is installed.
July 30, 2004
An EHR in the practice
Lessons Learned are one of the key drivers to new projects. If you have to learn something, its best to learn it from someone without pounding thy head against the wall. Unless you really like an infinite loop.
The AAFP has a study on what it takes to pilot and implement an electronic health care record in a family medicine practice setting.
What have they found?
Well one of the first steps what to track workflow. Very good, workflow tracking and determining what someone does is creating the as usecases and actor scenarios.
The next key finding, there are some bells and whistles we want. This is normally true of all projects implementations. There are key needs and then there are key desires, and there are also the pie in the sky desires. The trick of scope management is to deliver the needs and a couple of key desires, while avoiding the dreams.
Another finding, built-in templates would save them time. Great thought, clear repeatable processes save anyone time.
It was also discovered that the physicians needed a playground to learn the new system. Here the playground was offered fully throughout the implementation.
There was a frustration with the staged reiterative rollout quoting a key physician, "My only frustration is I want the project to move even faster". The truth be told a big bang initiative is always painful, rather staging pieces helps because clinicians have a lower learning curve for the new items. No one has to learn how to do their whole job function all at once on a new system.
Finally on the job learning is costly to productivity, this loss of productivity needs to be clearly defined in the pilot. Might I also suggest piloting in a different manner at different sites. See what items might make more sense to stage concurrently, and what items it makes sense to stage in sequence. Also have one site with more user training right before the live, and the other with the playground. These different approaches may yeild different losses in productivity. Obviously the approach with the least impact is the one you go with.
July 29, 2004
Risk Mitigation and Projects
In the software applications services industry you really have two types of activities operational maintenance and projects. Operational maintenance deals with the daily activities necessary to support the main business functions. Projects are the mechanism to align IT objectives with the strategic goals of the organization. All projects have a definite beginning and ending. While one is in the mist of a project issues crop up, these are normally reactive actions to a problem at hand. But let’s look at things a little more globally, your project may be effected by outside influence at some point down the road. The proactive identification of possible problems is normally known as a risk management.
Within your project having a standardized process to obtain, classify, and possibly mitigate risks is well worth your time. Just the identification is essential, it shows forethought for an item that has been considered. Once a risk is identified the strategy of handling it is determined. A risk can be accepted as is with no further mitigation attempts, otherwise it can be mitigated with one or several strategies. After the procedure to handle risks is established, a process to review the risk listing monthly, identify the owner of the risk and who is responsible for mitigating or monitoring it. This enables the risk listing to be communicated and it is clearly defined who to speak with if you are concerned about a risk on the list. Proactively handling risk will minimize the level of issues you need to reactively handle, and the approach will possibly have less of an impact on the project – just a thought.
July 28, 2004
Components & Constructors & Mach II
A question that pops up from time to time is when to use init() and when to use configure() within the framework.
Listeners, filters, and plug-ins are normally called using the configure method. This method even is called once on startup and cached. These objects inherit traits of the listener, filter, or plugin within the framework, respectively.
The init method constructs the instance of the object. If your object extends another object, you can have a call to super.init() to initialize the base component. This is normally utilized within your object structure. (DAO, Gateway, Transfer Object, Façade, ect)
July 27, 2004
Duplicate MRNO Terminology
Duplicate—more than one entry or file for the same person in a single facility level MPI
Overlap—more than one MPI entry or file for the same person in two or more facilities within an enterprise
Overlay—one MPI entry or file for more than one person (i.e., two people are erroneously sharing the same identifier)
What is an Enterprise Master Patient Index
An Enterprise Master Patient Index (EMPI) is a database that contains a unique identifier for every patient in the enterprise. This would include the medical center, outpatient clinics, practice offices and rehabilitation facilities. All registration systems would look to the EMPI to obtain patient information based upon several identifiers. Sometimes this is completed on the front by having the registrar utilize the EMPI searching capabilities. In other instances it is done after the registration process is completed via the system.
An EMPI will have either determininstic indexing where one can search based on an exact match of the combination of name, social security no, date of birth, and sex. The other searching mechanism is rules based via the first 4 letters of the last name, or other key identifiers. The best search mechanism is probabilistic searching via the soundex formula. This methodology improves the matching criteria.
A central repository of this information does several things. In clearly identifying a patient, it improves the care of the patient. If there is a clinical repository, a lifetime number that uniquely identifies one person is a tremendously valuable portion of information. Historical care related information can be obtained which is invaluable at the time of treatment, and also it can contain information from any clinic, rehab, or inpatient visit. The benefits of a centralized EMPI are great.
One thing to note about an EMPI, is there needs to be a mechanism for maintaining it in place, meaning staff and procedures. It may also be a good idea to audit the EMPI on a yearly basis to ensure there is quality data. You know the saying good stuff in good stuff out.
Recommended Data Elements:
Data Element |
Definition |
Enterprise identification number |
Primary identifier used by the enterprise to identify the patient across facilities (e.g., the enterprise number or corporate number |
Facility identifier |
Primary identifier used by the enterprise to identify the facility contributing data to the EMPI (e.g., the facility code) |
Internal patient identification |
Primary identifier used by the facility to identify the patient at admission (e.g., the medical record number) |
Person name |
Legal name of patient or person, including surname, given name, middle name or initial, name suffixes (e.g., Junior, IV), prefixes (e.g., Father, Doctor) |
Date of birth |
Patient or person's date of birth. Year, month, and day of birth are entered (e.g., YYYYMMDD). It is essential that the year of birth be recorded as four numbers, not just the last two numbers |
Gender |
Gender of patient (e.g., male, female, unknown/not stated) |
Race |
Race of patient. Race is a concept used to differentiate population groups largely on the basis of physical characteristics transmitted by descent. Races currently used by the federal government for statistical purposes are American Indian/Eskimo/Aleut, Asian or Pacific Islander, black, white, other, and unknown/not stated |
Ethnicity |
Ethnicity of the patient. Ethnicity is a concept used to differentiate population groups on the basis of shared cultural characteristics or geographic origins. Ethnic designations currently used by the federal government for statistical purposes are Hispanic origin, not of Hispanic origin, and unknown |
Residence |
Address or location of patient’s usual residence. Components include the street address, other designation (e.g., apartment number), city, state or province, zip or postal code, country, type of address (e.g., permanent, mailing) |
Alias/previous/maiden name |
Any names by which the patient has been known other than the current legal name, including nicknames, maiden name, previous name that was legally changed, etc. |
Social Security number |
Personal identification number assigned by the US Social Security Administration |
Telephone number |
Telephone number at which the patient can be contacted. This may be a home or business telephone number or the telephone number of a friend, neighbor, or relative |
This entry references:
AHIMA's Building an Enterprise Master Patient Index
Healthcare Informatics' Once is Enough
July 25, 2004
Evaluating an idea
New conventions come along all the time, along with new products. In order to get buyin to get people to want to use a new thing, it needs to do a couple of things.
First, it should be either cheaper than the competition or have less of an impact into workflow than another product
Second, it should have more value added features or just greater benefits.
Third, it shouldn't have a huge adoption cost, it should be easy to migrate from existing tools to the new one.
Finally, it should be easy to get at, readily available.
If you match 2 -3 of these points than that idea is a winner, otherwise go redraw.
July 24, 2004
Wait a bit CF
Here is a simple little sleep UDF. Hope it helps out.
<cffunction name="sleep" access="public" returntype="numeric">
<cfargument name="timePeriod" type="numeric" required="true" hint="The time in seconds you want the program to wait" />
<cfset var sleepTime = JavaCast("int", timePeriod * 1000) />
<cfset var objThread = createObject('java', 'java.lang.Thread') />
<cfset objThread.sleep(sleepTime) />
<cfreturn sleepTime>
</cffunction>
What are design patterns
A while ago I went over the types of design patterns, but I’m getting the impression that a lot of people are unclear on what design patterns are. Design patterns are a recipe for solving common software architectural problems. Object-oriented design has been around for a while, and as people become more accustom to using object oriented techniques they realized something. There are a couple of ways to do something, that results in a better architectural structure of the software application, then other ways. Out of these realizations arose techniques which are known as design patterns.
So people needed a way to communicate these techniques, out of this need for communication arose a common jargon. This realization is probably best illustrated with the first 23 design patterns. The communication of these techniques is important because we don't have time now-a-days to all be wheel inventors. The other thing is that after someone understands how these patterns work and can be applied it elevates their level of architectural enlightenment. In other words they become better at architecting solutions.
In order to communicate patterns, a pattern has key features.
Feature |
Description |
Name |
The term used to refer to the pattern |
Intent |
What the pattern is suppose to accomplish |
AKA |
Synonyms or other ways to refer to the pattern |
Problem |
An architecture issue and how the pattern can be applied to resolve it. |
Applicability |
Common scenarios where you can use the pattern |
Structure |
A diagram that illustrates the How-To |
Participants and Collaborators |
The entities that are involved, what they do, and how they do it. |
Consequences |
The advantages/ Disadvantages of the pattern and the grey area that surrounds using the pattern in this manner. |
Free ColdFusion Applications
Chris Cantrell blogged about this a while ago, but there are several free cf applications for your persual found at http://www.freecoldfusionapplications.com/
ColdPattern
Tom Chiverton in conjunction with a couple of others have started the Cold Pattern project. Its a good idea, and can be a very useful tool. Its starting out covering just a few patterns the mediator and facade. Let's hope it grows!
Structures in CFMX
CF uses structures quite a bit, there are several internal structures within CF, this encompasses all variable scopes and these can be exploited utilizing structure functions.
First the structures in CF are
- Application
- CGI
- Session
- Client
- URL
- Form
- Request
- Server
- Cookie
- Attributes
- CFCatch
- CFError
- CFFtp
- CFHttp
- File
- ThisTag
So let's say you wanted to clear session variables, try using
<cfscript>
structclear(session);
</cfscript>
Or let's say you wanted to verify that a form submission caused an action page.
<cfif structkeyexists(form, "fieldvalue")>
There are several uses that can be manipulated.
JACHO Quality Website
Quality Check is a website that allows consumers to compare treatment quality in about 16,000 facilities nationwide for heart attack, heart failure, pneumonia, and pregnancy.
Surfing it is a little clunky but the accreditation viewing is very informative.
Most Wired Findings
As you are aware the most wired and most wireless survey has arrived! The article summarizing the findings and criticalities can be found here.
A couple of items in the article that caught my eye.
First, the way that the most wired hospitals go above and beyond the normal process.
- More than 90 percent of the Most Wired conduct either pre- or post-implementation return-on-investment analyses to justify expenditures, compared with only 59 percent of the least wired. The least wired are the 100 respondents who scored the lowest on the survey.
- The Most Wired have a wide variety of offerings available over the Internet for patient service and customer support, ranging from online patient registration to disease specific self-triage.
- IT education is a priority among the Most Wired hospitals and health systems. The Most Wired have doctors and nurses dedicated to IT training and support. The Most Wired are also beginning to offer continuing medical education credits to participate in technology training.
- The Most Wired have significantly higher adoption rates among doctors and nurses across a broad set of clinical activities, such as clinical order entry and results review, compared with the least wired hospitals.
Second, wiring relate directly to medication safety. Having a usable clinical system for medication orders allows medication safety to at the beginning of the ordering process, not the backend.
The least wired are also more likely to have medications that are ordered manually, meaning that the medication never appears as an electronic order. A whopping 20 percent of medications at the least wired organizations are ordered manually. This compares with an average of 3.1 percent of medications ordered manually at the Most Wired.
Once the order is in the system, the correct drug must be dispensed. Nearly 35 percent of the Most Wired say that the lion's share of their medications--81 to 100 percent--are electronically matched to the patient and order at the time of administration. This compares with only 5 percent of the least wired. And 84 percent of least wired organizations do not electronically match any medications to the patient at the time of administration
Finally the best point of the article is that training drives adoption, in other words people will use that which they are familiar with, you just need to get them over the fear of knowning hump.
According to survey results, more than 95 percent of the Most Wired have a nurse dedicated to IT training, compared with 41 percent of the least wired. More than 60 percent of the Most Wired have a physician dedicated to IT training, compared with 3 percent of the least wired. Eight percent of the least wired--roughly one in 12--do not provide any educational resources on IT whatsoever
Its a very good article and a great survey. I wonder where AMC came out in the survey...
JCAHO on Bar-Coding.
The Joint Commission on Accreditation of Healthcare Organizations (JCAHO) has recinded the bar-coding system proposal in hospitals as a mechanism to ensure correct medications are given to patients. The AHA advised that the proposal limited the technological solution to only one mechanism, and that isn't a great idea. Because with new innovations, it may turn out that bar-coding isn't the silver bullet, something else may be.
The National Patient Safety Goals for 2005 and 2004 may be found here.
July 23, 2004
Getting the Top 10 MySQL Query Results.
Top 5 doesn't work too well in selecting SQL statements in MySQL. However an operator that limits the size of the result set is LIMIT.
For example,
SELECT * FROM tbl LIMIT 10;
July 22, 2004
The 100 most wired
The most wired report has come out, it looks like wireless and EHR are on the rise!
To see the wsj article on the report, click here.
To see the report, please click here.
Netcraft
Netcraft services has a neat little tool. Place in the site, and you can see some of its history.
The site displays the OS, WebServer, Last Changed, IP Address, and Net block owner.
It will show the history of a site from hosting providers to web server upgrades.
July 19, 2004
Implementation Checklist
We all know the time, its at the end of a long project. There are several things to move live in just the right order. Some items we can do ourselves, others we need assistance from other members of our team.
It may be a good practice to take the time, before moving a project into production to review an implementation checklist with members of your team. This checklist consists the sequence of events and activities needed for the live event. The review group would consist of a business representative, the IT personel, and maybe even operations team members. The checklist serves several purposes. First it makes sure that you have everything you need listed, and other eyes can help out here (They may find that forgotten something) Secondly, it conveys the overall live implementation plan and allocates resource responsibility appropriately. Everyone understands who is doing what.
July 18, 2004
Color Picker
Good Designers just have an eye for great color schemes. Others like me are sadly in need of great help.
One site that offers such help can be found here.
Another great tool is color wheel pro:
Color Wheel Pro - a program that allows you to see color theory in action: you can create harmonious color schemes and preview them on real-world examples
Free download is also cool!
July 17, 2004
New Whois
As Ben Forta pointed out, Network Associates has released an improved whois search found here.
FuseBox 4.1 Release
Received another one of those teratech letters, and it looks like at Fusebox 4.1 is going to be released at Fusebox 2004.
So I went over to the forumsand fusebox.org -- no feature page. Just a couple of google search returns about fusebox 4.1 about the proposed alpha changes.
What I would really like to see when we go into these new versions of frameworks is a feature list, but a case study of the improvements in construction at a corporation. Either the fact that with having all staff trained and using this framework technique has increased productivity and project lags by this much. I know its a dream world, but it would really help anyone explaining the pros and cons to management.
If we can come up with few key measures that are indicators of productivity in regards to maintaining software, and then broadcast them as a part of the framework utilization, being fusebox, mach-ii, or on-tap. Measuring the rate of success, would probably be very beneficial. Just a thought.
July 16, 2004
Don't forget to minimize the browser
For one of the ongoing checklists to web programming, I think one needs to test by minimizing the browser tool. It really helps to show the positioning of items on a page. IMHO, It depicts issues with layout in a crystal clear manner.
Thoughts?
Why deploy a Content Managment System
Two Step Designs has recently published an article on Successfully Deploying a Content Management System. It is definitely worth the read.
A couple of the pointers of the article are:
<--- Snipped from article --->
The purpose of the content management project is rarely to just install the CMS. Instead, the overall goals of the project are likely to include:
improve the design or structure of the intranet
ensure the content is up-to-date and accurate
improve the effectiveness of the site
reduce duplication of content
improve content management processes
Another key point is that content needs to have clearly identified owners in place, I would even go as far as to suggest that a clearly defined owner and authorization structure for any CMS implementation is a large benefit.
For example, if one would like to implement content update, have maybe corporate compliance, legal, and marketing approve the content. For healthcare, have a dedicated clinician assigned with the editorial task.
July 14, 2004
Verify a dsn connectivity on the fly
Every once in a while, you may want to have logic to verify the data source within your code. The following trick will work.
<cfset variables.lockname = CreateUUID() />
<cflock name="#variables.lockname#" type="exclusive" timeout="10">
<cfscript>
factory = CreateObject("java", "coldfusion.server.ServiceFactory");
ds_service = factory.DataSourceService;
isOk = ds_service.verifyDatasource("#Application.dsn#");
</cfscript>
</cflock>
User Acceptance
Moving things live into production is when IT has the most impact upon a business. The customers may experience a downtime, their workflow maybe changing, or many other situations. It is also the time that truly determines if the change meets the customers requirements. Or is it?
One practicality that may be implemented before moving a change into production is the completion of user acceptance testing. Then there is the actually signing of the user acceptance of the project or request. This should be done by both the requestor, and honestly the authorizer also. The requestor is the individual who made the request for work, and the authorizer approved the work to be completed. This way everyone involved in requesting the change is involved. And ideally the specs of the change are met before it is implemented into product.
That’s a better mechanism, than implementing and finding out...
"oh, it functions that way?"
To Dump the CF Schedule
From the post the other day, to dump the CF Schedule, try using
<cflock name="serviceFactory" type="exclusive" timeout="10">
<cfscript>
factory = CreateObject("java", "coldfusion.server.ServiceFactory");
cron_service = factory.CronService;
ServicesList = cron_service.listALL();
</cfscript>
<cfdump var="#ServicesList#">
</cflock>
The top ten CPOE Challenges
Health Data Management recently published an article listing the top ten CPOE Challenges.
1. Physician Resistance
2. Top-Down Committment
3. Cost
4. Changing Workflow
5. Developing Order Sets
6. Time to Enter Orders
7. Technology Limits
8. Measuring Success
9. Training Issue
10. Managing Expectations
July 13, 2004
Character Encoding
Character encoding is CF is a fun thing. If you need to pass variables to java functions that require a different coding standard try manipulating the variable.
First set the variable up in either form or url scope
<cfset FORM.stringvalue = "password string">
Then set the encoding to your desired flavor:
<cfscript>
SetEncoding("FORM", "iso-8859-1");
WriteOutput("FORM.stringvalue is " & FORM.stringvalue & "
");
</cfscript>
July 12, 2004
Reading an XML doc & Mach II
Reading an XML doc & Mach II
Let’s say it has come to a time, when you would like to read in an XML doc as a data source within the MachII framework. I'm going to use the XML doc from this previous post.
How does one go about doing that?
First within the model folder, set up the following structure
\input\xmlListener.cfc
\input\xmlGateway.cfc
Your xmlListener will look like:
<cfcomponent extends="MachII.framework.Listener" displayname="XML Listener" hint="I am the listener for xml Documents">
<cffunction name="configure" access="public" returntype="void" output="true" displayname="Blog Constructor" hint="I initialize this listener as part of the framework startup.">
<cfscript>
variables.xmlGateway = createObject("component","xmlReader.model.input.xmlGateway").init();
</cfscript>
</cffunction>
<cffunction name="getAll" access="public" returntype="query" output="false" displayname="Get XML doc" hint="I return a query containing the XML Doc.">
<cfreturn variables.xmlGateway.findAll() />
</cffunction>
<cffunction name="getTotalChildren" access="public" returntype="numeric" output="false" displayname="Get the Number of Aggregated Blogs" hint="I return the number of xmlChildren of the root">
<cfreturn variables.xmlGateway.findTotal() />
</cffunction>
</cfcomponent>
Your xmlGateway will appear as:
<cfcomponent displayname="XML Gateway" hint="I am a data gateway to Summarize an XML document">
<cffunction name="init" access="public" returntype="xmlReader.model.input.xmlGateway" output="false" displayname="Gateway Constructor" hint="I initialize the XML gateway.">
<cfset var inputXML = "" />
<cfset variables.structXML = 0 />
<cffile action="read" variable="inputXML" file="#ExpandPath("data\xmlDOC.xml")#" />
<cfset variables.structXML = XMLParse(inputXML) />
<cfreturn this />
</cffunction>
<cffunction name="findAll" access="public" returntype="query" output="false" displayname="Find All" hint="I return a query containing the XML Doc">
<cfset var qrySelect = 0 />
<cfset var structListing = 0 />
<cfset var patientName = 0 />
<cfset var patientID = 0 />
<cfset var visitID = 0 />
<cfset var admitDate = 0 />
<cfset var payor = 0 />
<cfset var nurseStation = 0 />
<cfset var roomBed = 0 />
<cfset var service = 0 />
<cfset var previousDischargeDate = 0 />
<cfset var selectRow = 0 />
<cfset structListing = XMLSearch(structXML, "/ReadmissionReport/Readmission") />
<cfset qrySelect = QueryNew("patientName, patientID, visitID, admitDate, payor, nurseStation, roomBed, service, perviousDischargeDate") />
<cfloop from="1" to="#ArrayLen(structListing)#" index="i">
<cfset patientName = structListing[i].PatientName.XmlText />
<cfset patientID = structListing[i].PatientID.XmlText />
<cfset visitID = structListing[i].VisitID.XmlText />
<cfset admitDate = structListing[i].AdmitDate.XmlText />
<cfset payor = structListing[i].Payor.XmlText />
<cfset nurseStation = structListing[i].NurseStation.XmlText />
<cfset roomBed = structListing[i].RoomBed.XmlText />
<cfset service = structListing[i].Service.XmlText />
<cfset selectRow = QueryAddRow(qrySelect) />
<cfset QuerySetCell(qrySelect, "patientName", patientName, selectRow) />
<cfset QuerySetCell(qrySelect, "patientID", patientID, selectRow) />
<cfset QuerySetCell(qrySelect, "visitID", visitID, selectRow) />
<cfset QuerySetCell(qrySelect, "admitDate", admitDate, selectRow) />
<cfset QuerySetCell(qrySelect, "payor", payor, selectRow) />
<cfset QuerySetCell(qrySelect, "nurseStation", nurseStation, selectRow) />
<cfset QuerySetCell(qrySelect, "roomBed", roomBed, selectRow) />
<cfset QuerySetCell(qrySelect, "service", service, selectRow) />
</cfloop>
<cfreturn qrySelect />
</cffunction>
<cffunction name="findTotal" access="public" returntype="numeric" output="false" displayname="Find Total" hint="I return the number of readmits in the xml file">
<cfset var xmlNode = 0 />
<cfset xmlNode = structXML.XMLRoot>
<cfreturn ArrayLen(xmlNode.xmlChildren)>
</cffunction>
</cfcomponent>
Next within the config folder, add the following to the machii.xml under Listeners.
<listener name="xmlListener" type="xmlReader.model.input.xmlListener"> <invoker type="MachII.framework.invokers.CFCInvoker_Event" /> </listener>
And add this under event handler to call the listener to the desired event
<notify listener="xmlListener" method="getTotalChildren” resultKey="request.intTotal" /> <notify listener="xmlListener" method="getAll" resultKey="request.qryAll" />
And within the view add the following logic to see the total and query
#request.intTotalChildren# #request.qryAll#
July 11, 2004
CSS, Reusability and MachII
One of the arguments to present to move to MachII as a way of developing for a team. Is the aspect of reusability.
Mach II, and CSS fit exceptionately nicely together. Why? Simply Page Views.
Let me elaborate. Let's say your page has three column layout -- the navigation, the entry, and the sidebar. What one can do is have a view set up for each of the elements. IE Navigation.cfm, Entry.cfm, and Sidebar.cfm
So using css layout allows you just to change the appearance of the storefront, not the inner working inside.
So your style sheet looks like the following:
body {
font-family: Arial, Helvetica, sans-serif;
font-size:11px;
margin: 0;
padding: 0;
background:rgb(95%, 95%, 95%);
color: black;
}
h1 {
font-size:200%;
text-transform:lowercase;
letter-spacing:3px;
margin:0;
padding:0.66em 0 0.33em 16%;
background:rgb(85%,85%,70%);
}
#navigation{
position:absolute;
font-size:11px;
top: 3em;
left: 0;
width: 12.5%;
border: 1px solid black;
z-index:10;
}
#navigation a{
display:block;
padding:4px 8px;
margin:0;
text-align:right;
border-top:1px solid gray;
}
#navigation a:hover{
background:#FB9;
}
#navigation h4{
background: rgb(33%,33%,33%);
color:white;
text-align:center;
margin:0;
padding:0.25em 0 0.125em 0;
}
#entry{
margin:0 20% 1em 20%;
padding:0;
}
#sidebar{
position:absolute;
top:4em;
right:0;
width:20%;
font-size:10px;
z-index:11;
}
#sidebar h4{
background: rgb(70%,70%,55%);
color:black;
margin:0;
padding:0.25em 0 0 0.5em;
}
#sidebar a{
display:block;
padding:8px 0 2px 10px;
margin:0;
border-top:1px solid rgb(85%, 85%, 85%);
}
#sidebar a:hover {
background:rgb(85%,85%,85%);
}
Therefore Navigation.cfm looks like
<div id="Navigation">
<p> <a href="./index.cfm?event=home" title="AccessKey: h" accesskey="h">Home</a> <br />
<a href="./index.cfm?event=news" title="AccessKey: f" accesskey="f">faq</a> <br />
<a href="./index.cfm?event=business" title="AccessKey: r" accesskey="r">resources</a> <br />
<a href="./index.cfm?event=techologists" title="AccessKey: a" accesskey="a">about</a></p>
</div>
And your Entry.cfm view would look like
<div id="entry">
<p>The norm of reciprocity is the human tendency to respond to the actions of others with similar actions. If we are treated with contention and distrust, we tend to treat others with contention or distruct. If we are treated by someone with a warm friendly manner, we tend to treat others in a warm friendly manner.</p>
<p>Hostile interactions evolve out of one's tendency to take an exaggerated view of others' perceived hostility or unreasonable behavior. Then the exaggeration causes one to reciprocate with negative behavior. These hostile interactions end up being a self-fulfilling prophecy with each side behaving equally negatively.</p>
<p>Some triggers of this behavior are Naive realism, where people tend to assume that their view of the world reflects the reality of the world. Confirmatory bias is another trigger where we seek to confirm our beliefs or to find flaws. Also accuse bias is another scenario where someone intentionally does one harm, then it is human nature to hold the party responsible for a long time. On the flip side of things, excuser bias is the tendency to focus on factors outside of our control, while turning a blind eye to factors within our control. </p>
<p>Cooperative interactions is triggered by people's perceptions of fairness, the ability to realize that reasonable people will come to different conclusions, (many ways to skin a cat), the ability to accept responsibility for problems, and finally the ability that you don't blame others for the problem exclusively. </p>
</div>
And finally the Sidebar.cfm view would look like
<div id="sidebar">
<a target="_blank" title="A architect's view" href="http://www.corfield.org/blog/">Sean Corfield</a><br />
<a target="_blank" title="Raymond Camden" href="http://www.camdenfamily.com/morpheus/blog/">Raymond Camden</a><br />
<a target="_blank" title="Steve Nelson" href="http://steve.secretagents.com/index.cfm?fuseaction=fuseblog.MainPage">Steve Nelson</a><br />
</div>
So then in Mach-ii the event handlers look like
<event-handler event="home" access="public">
<view-page name="Navigation" />
<view-page name="Entry" />
<view-page name="SiteBar" />
</event-handler>
<page-view name="Navigation" page="/views/Navigation.cfm" />
<page-view name="Entry" page="/views/Entry.cfm" />
<page-view name="SiteBar" page="/views/SiteBar.cfm" />
July 10, 2004
Looking at the scheduled tasks without the CFAdmin
Here is a nice little cfc to get access to the CF Scheduler tasks running on your cf box without having to utilize the administrator.
hint="CFMX Scheduled Tasks editor"
lastUpdated="2004-07-09"
author="Elyse Nielsen">
<!--- Initialization --->
<cfset THIS.lockname = CreateUUID()>
<cflock name="#THIS.lockname#" type="exclusive" timeout="10">
<cfscript>
this.factory = CreateObject("java", "coldfusion.server.ServiceFactory");
this.cron_service = this.factory.CronService;
this.Services = this.cron_service.listALL();
</cfscript>
</cflock>
<cfif not IsArray(this.Services)>
<cfthrow message="The template '#lcase(getfilefrompath(getcurrenttemplatepath()))#' can't initialize.">
</cfif>
<cffunction name="getScheduledTask" access="public" output="false" returnType="any"
hint="Returns the structure of the Scheduled Task if found by name">
<cfargument name="taskname" type="string" required="true">
<cflock name="#THIS.lockname#" type="exclusive" timeout="10">
<cfloop from="1" to="#ArrayLen(this.Services)#" index="i">
<cfif this.Services[i].task IS taskname>
<cfreturn this.Services[i]>
</cfif>
</cfloop>
</cflock>
<cfreturn "">
</cffunction>
<cffunction name="showScheduledTasks" access="public" output="false" returntype="array" hint="I return an array of structures of the scheduled tasks">
<cflock name="#THIS.lockname#" type="exclusive" timeout="10">
<cfreturn this.Services>
</cflock>
</cffunction>
</cfcomponent>
One can use cfschedule to accomplish the update, deleting, or running information.
One aside, I wish that that there was a way to add a isDisabled function for times when one needs to have the cron utility stopped. This would be a great feature in Blackstone or the next version. IMHO, it beats having to play with the end dates of the tasks.
July 9, 2004
PDF Encryption with CFMX & FOP
Sometimes it is necessary to encrypt pdf documents considering the information that is contained within them.
Apart of the FOP has built in support for PDF Encryption, by tweaking nateweiss’s FOP.cfc and doing a little configuration work things go pretty smoothly.
To set up CF for the encryption
1. Download the latest binary of FOP from apache.
2. Download the Java Cryptography Extensions (JCE) library extension from bouncy castle.
3. To the add java.security file in C:\CFusionMX\runtime\jre\lib\security the following line to the list of providers
security.provider.6=org.bouncycastle.jce.provider.BouncyCastleProvider
4. For a standalone installation place the following files in the C:\CFusionMX\runtime\lib
- fop.jar
- Avalon-framework-cvs-20020806.jar
- batik.jar
- jce-jdk13-124.jar
5. In the CF administrator, under Java and JVM Settings add “C:\CFusionMX\runtime\lib\jce-jdk13-124.jar,C:\CFusionMX\runtime\lib\fop.jar,” to the class path
6. Restart ColdFusion MX Application Server Service
The EncryptedFOP.cfc:
<cfcomponent>
<!--- Initialize the FOP driver from xml.apache.org --->
<cfset THIS.fopdriver = CreateObject("java", "org.apache.fop.apps.Driver")>
<cfset THIS.lockname = CreateUUID()>
<cffunction name="ConvertFileToPDF" access="public">
<cfargument name="foFile" type="string" required="true">
<cfargument name="pdfFile" type="string" required="true">
<cfargument name="userPassword" type="string" required="true">
<cfargument name="ownerPassword" type="string" required="true">
<!--- Set up Java input source --->
<cfset var input = CreateObject("java", "org.xml.sax.InputSource")>
<cfset input.init( ARGUMENTS.foFile)>
<!--- Proceed with PDF generation --->
<cfset private_generateEncryptedPDF(input, pdfFile, userPassword, ownerPassword)>
</cffunction>
<cffunction name="ConvertStringToPDF" access="public">
<cfargument name="foString" type="string" required="true">
<cfargument name="pdfFile" type="string" required="true">
<cfargument name="userPassword" type="string" required="true">
<cfargument name="ownerPassword" type="string" required="true">
<!--- Set up Java input source --->
<cfset var reader = CreateObject("java", "java.io.StringReader")>
<cfset var input = CreateObject("java", "org.xml.sax.InputSource")>
<cfset reader.init(foString)>
<cfset input.init(reader)>
<!--- Proceed with PDF generation --->
<cfset private_generateEncryptedPDF(input, pdfFile, userPassword, ownerPassword)>
</cffunction>
<cffunction name="private_generateEncryptedPDF" access="private">
<cfargument name="input" type="any" required="true">
<cfargument name="pdfFile" type="string" required="true">
<cfargument name="userPassword" type="string" required="true">
<cfargument name="ownerPassword" type="string" required="true">
<!--- Output stream for writing PDF file --->
<cfset var output = CreateObject("java", "java.io.FileOutputStream")>
<!--- Rendering options for encrypting PDF file --->
<cfset var rendererOptions = CreateObject("java","java.util.HashMap")>
<!--- Get ready to do the PDF generation --->
<cflock name="#THIS.lockname#" type="exclusive" timeout="10">
<cflock name="#ARGUMENTS.pdfFile#" type="exclusive" timeout="10">
<!--- Turn on the output stream --->
<cfset output.init( ARGUMENTS.pdfFile )>
<!--- Set the rendering options --->
<cfset rendererOptions.put("ownerPassword", "#ownerPassword#")>
<cfset rendererOptions.put("userPassword", "#userPassword#")>
<cfset rendererOptions.put("allowCopyContent", "FALSE")>
<cfset rendererOptions.put("allowEditContent", "FALSE")>
<cfset rendererOptions.put("allowPrint", "FALSE")>
<cfset rendererOptions.put("allowEditAnnonations", "False")>
<!--- Hook the FOP driver to the input/output --->
<cfset THIS.fopDriver.setInputSource(input)>
<cfset THIS.fopDriver.setOutputStream(output)>
<cfset THIS.fopDriver.setRenderer(THIS.fopDriver.RENDER_PDF)>
<cfset THIS.fopDriver.getRenderer().setOptions(rendererOptions)>
<!--- Perform the actual PDF generation --->
<cfset THIS.fopDriver.run()>
<!--- Turn off the output stream --->
<cfset output.close()>
</cflock>
</cflock>
</cffunction>
</cfcomponent>
To Invoke the CFC
July 8, 2004
Web Services a quickie
Web Services is a term that has come to encompass the ways for discovering software as services accross the web. Services can be truly exploited with CFMX in a very easy manner.
Web services group together several different technologies, SOAP, WSDL, and UDDI. Simple Object Access Protocal, SOAP, is an XML envelope describing how to use and what is there. In addition within the envelop is the rules for how to process. WSDL or Web Services Description Language is an XML of the service interface and directions of how to use. UDDI is short for Universal Description, Discover, and Integration and is the way to describe a web service. UDDI registries allow business to publish and query existing web services.
Using Web Services is exceptionately easy with coldfusion.
For example here is a Service that calculates BMI: I had the file in the http://localhost/bmi/bmi.cfc of my development maching.
<cffunction name="calculateBMI" access="remote" returntype="numeric" hint="This function calculates an individuals Body Mass Index">
<cfargument name="WeightLbs" type="numeric" required="yes" hint="The person's weight in pounds">
<cfargument name="HeightInches" type="numeric" required="yes" hint="The person's height in inches">
<cfset HeightInchesSquared = HeightInches * HeightInches>
<cfset WHI = WeightLbs / HeightInchesSquared>
<cfset BMI = WHI * 703>
<cfreturn DecimalFormat(BMI)>
</cffunction>
</cfcomponent>
And here is an example consuming that service
<cfinvoke webservice="http://localhost/bmi/bmi.cfc?wsdl" method="calculateBMI" returnvariable="varBMI">
<cfinvokeargument name="WeightLbs" value="140">
<cfinvokeargument name="HeightInches" value="72">
</cfinvoke>
And finally so everything is in one place here is an example of the wsdl for that service.
<?xml version="1.0" encoding="UTF-8" ?>
- <wsdl:definitions targetNamespace="http://bmi" xmlns:impl="http://bmi" xmlns:intf="http://bmi" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns1="http://rpc.xml.coldfusion" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
- <wsdl:types>
- <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://rpc.xml.coldfusion">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
- <complexType name="CFCInvocationException">
<sequence />
</complexType>
</schema>
</wsdl:types>
- <wsdl:message name="CFCInvocationException">
<wsdl:part name="fault" type="tns1:CFCInvocationException" />
</wsdl:message>
- <wsdl:message name="calculateBMIResponse">
<wsdl:part name="calculateBMIReturn" type="xsd:double" />
</wsdl:message>
- <wsdl:message name="calculateBMIRequest">
<wsdl:part name="WeightLbs" type="xsd:double" />
<wsdl:part name="HeightInches" type="xsd:double" />
</wsdl:message>
- <wsdl:portType name="bmi">
- <wsdl:operation name="calculateBMI" parameterOrder="WeightLbs HeightInches">
<wsdl:input name="calculateBMIRequest" message="impl:calculateBMIRequest" />
<wsdl:output name="calculateBMIResponse" message="impl:calculateBMIResponse" />
<wsdl:fault name="CFCInvocationException" message="impl:CFCInvocationException" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:binding name="bmi.cfcSoapBinding" type="impl:bmi">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="calculateBMI">
<wsdlsoap:operation soapAction="" />
- <wsdl:input name="calculateBMIRequest">
<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://bmi" />
</wsdl:input>
- <wsdl:output name="calculateBMIResponse">
<wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://bmi" />
</wsdl:output>
- <wsdl:fault name="CFCInvocationException">
<wsdlsoap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://bmi" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name="bmiService">
- <wsdl:port name="bmi.cfc" binding="impl:bmi.cfcSoapBinding">
<wsdlsoap:address location="http://localhost/bmi/bmi.cfc" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Exploring Java & CF
Ever want to take an indepth look at the functionality of a java object within cf.
This code may help you out
<cfset keystoreType="JKS">
<cfset lockname = CreateUUID()>
<cflock name="#lockname#" type="exclusive" timeout="10">
<cfscript>
keyStore = CreateObject("java", "java.security.KeyStore");
ks = keyStore.getInstance(keystoreType);
</cfscript>
<cfdump var="#ks#">
</cflock>
July 2, 2004
He3 beta
He3 beta has been released at http://richpalette.com. In addition there is a mailing list via the House of Fusion.
He3 is a new IDE for CF within the eclipse tool. Built upon eclipse, He3 has support for the Fusebox 4 and Mach-II Frameworks.