<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>premiertec : blog</title>
	<atom:link href="http://www.premiertec.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.premiertec.com/blog</link>
	<description>Oracle eBusiness Architects</description>
	<pubDate>Tue, 20 Apr 2010 06:30:07 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Oracle skills shortage in an economic downturn</title>
		<link>http://www.premiertec.com/blog/oracleskillsshortage/</link>
		<comments>http://www.premiertec.com/blog/oracleskillsshortage/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 14:40:40 +0000</pubDate>
		<dc:creator>gallant_g</dc:creator>
		
		<category><![CDATA[Asset Management]]></category>

		<category><![CDATA[Implementation]]></category>

		<category><![CDATA[R12]]></category>

		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[ADF]]></category>

		<category><![CDATA[Enterprise Asset Management]]></category>

		<category><![CDATA[FSAH]]></category>

		<category><![CDATA[OA Framework]]></category>

		<category><![CDATA[Oracle Contracts]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=131</guid>
		<description><![CDATA[One of our recruiters was asked by a customer why it was difficult to find the right skills for an Oracle E-Business Suite project. It felt like a strange question to hear in the current economic climate - especially while so many IT professionals are affected by unemployment - but he had a point, there [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: 12pt; line-height: 115%;">One of our recruiters was asked by a customer why it was difficult to find the right skills for an Oracle E-Business Suite project. It felt like a strange question to hear in the current economic climate - especially while so many IT professionals are affected by unemployment - but he had a point, there will always be Oracle skills that are hard to find.<span id="more-131"></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: 12pt; line-height: 115%;">The Oracle skills market has changed more in the last two years than it has in the last two decades. The economic downturn has undoubtedly slowed a significant amount of project churn, which in turn has given a greater transparency of what skills really are in demand, together with a sudden and perhaps harsh view of what skills have been left on the shelf.<span style="mso-spacerun: yes;"><br />
</span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: 12pt; line-height: 115%;">Oracle EBS Functional consultants have had a busy time since the new millennium. The demand for these skills led to more people entering these roles without the previously necessary academic credentials. Since the recent economic downturn, many Functional consultants would argue that they have never seen this level of uncertainty before. Functional Core Financials and Oracle CRM consultants have perhaps seen the slowest times of all Oracle consultants, I could name a dozen people in my own network who have thrown in the laptop and moved out of the Oracle world altogether.<span style="mso-spacerun: yes;"> </span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: 12pt; line-height: 115%;">Oracle EBS Technical consultants have seen their demand change over the years. While there is still demand for technical EBS skills, Oracle users are using less customisations in their solutions, and we have seen a lot of technical consultants move towards more functional duties.<span style="mso-spacerun: yes;"> </span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: 12pt; line-height: 115%;">Throughout the nineties the traditional Oracle consultant was more likely to be a SQL Forms or SQL Reports developer. In a keynote speech in 2000, Larry Ellison announced that <em style="mso-bidi-font-style: normal;">“In the future there will be two types of technical Oracle Consultant: a Java Architect and a DBA”. </em>Whilst the Oracle community at the time were sceptical about this statement, it has been heading in that direction ever since: the recent acquisition of Java has been described as “the most important software Oracle has ever acquired.” </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: 12pt; line-height: 115%;">Having asked our Consultancy team, our recruiters and our customers what technical skills they consider the most difficult to find, the most common answer is <strong style="mso-bidi-font-weight: normal;">OA Framework</strong> and <strong style="mso-bidi-font-weight: normal;">ADF</strong>. I have asked the same question for Oracle EBS Financials functional knowledge and the answer is <strong style="mso-bidi-font-weight: normal;">FSAH </strong>and <strong style="mso-bidi-font-weight: normal;">E-Biz Tax</strong>. Fusion Middleware and SOA/BPEL skills still continue to be in demand.</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;"><span style="font-size: 12pt; line-height: 115%;">Whilst there is a distinct shortage in these skills, as well as specialist modules such as <strong style="mso-bidi-font-weight: normal;">Oracle Contracts</strong> and <strong style="mso-bidi-font-weight: normal;">Oracle</strong> <strong style="mso-bidi-font-weight: normal;">Enterprise Asset Management</strong>, we could argue that the term “skills shortage” could appear a little insulting to those who have been benched in recent months (or even years), so perhaps we need to characterise the problem as a “skills transfer” issue. </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt;">George Gallant - March 2010</p>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/oracleskillsshortage/feed/</wfw:commentRss>
		</item>
		<item>
		<title>So anyway why do you call it IWMS?</title>
		<link>http://www.premiertec.com/blog/what-is-iwms/</link>
		<comments>http://www.premiertec.com/blog/what-is-iwms/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 12:04:32 +0000</pubDate>
		<dc:creator>gallant_g</dc:creator>
		
		<category><![CDATA[Asset Management]]></category>

		<category><![CDATA[Implementation]]></category>

		<category><![CDATA[EAM]]></category>

		<category><![CDATA[IWMS]]></category>

		<category><![CDATA[Property Manager]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=116</guid>
		<description><![CDATA[I was asked this question by a customer during a recent demonstration of Premiertec’s Integrated Workplace Management System.
IWMS – The Background
The term “Integrated Workplace Management System”, or “IWMS” (to satisfy our lust for acronyms), originated from a university academic, and was subsequently co-opted by Gartner. Up until recently, Gartner produced an IWMS market assessment, including [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">I was asked this question by a customer during a recent demonstration of Premiertec’s <strong style="mso-bidi-font-weight: normal;">Integrated Workplace Management System.</strong></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><strong style="mso-bidi-font-weight: normal;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">IWMS – The Background</span></strong></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">The term “Integrated Workplace Management System”, or “IWMS” (to satisfy our lust for acronyms), originated from a university academic, and was subsequently co-opted by Gartner. Up until recently, Gartner produced an IWMS market assessment, including a <em style="mso-bidi-font-style: normal;">Gartner Magic Quadrant</em>, and without a common term like IWMS there would have been no other way to group a load of vendors together in a comparison document. <span id="more-116"></span></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">During their initial analysis of the facilities and real estate space, it was observed that the market was moving from point solutions to <strong style="mso-bidi-font-weight: normal;">integrated</strong> solutions. It was also observed that there was a trend toward defining the facilities and real estate domain more broadly as <strong style="mso-bidi-font-weight: normal;">workplace management</strong>, to recognise the advent of workplace mobility and the solutions needed to manage the virtual workplace. Thus, the two trends were combined to the single acronym IWMS.</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">Although it is recognised that the IWMS definition is very broad, and therefore less useful to describe a market that is becoming more industry verticalized, users still need a coherent framework to evaluate vendors and market trends. Many vendors have used the IWMS blueprint provided in the IWMS market analysis containing the <em style="mso-bidi-font-style: normal;">Magic Quadrant </em>to enhance their products and re-align their messages. </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><strong style="mso-bidi-font-weight: normal;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">So why do<em style="mso-bidi-font-style: normal;"> we</em> call it IWMS?</span></strong></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">If you type IWMS into Wikipedia you get the following description:<br />
<em style="mso-bidi-font-style: normal;">IWMS is an enterprise platform that supports the planning, design, management, utilization and disposal of an organisation’s location based assets. IWMS systems assist organisations in optimizing the use of workplace resources, including the management of a company’s real estate portfolio, infrastructure and facilities assets. Four of the primary areas of functionality include <strong style="mso-bidi-font-weight: normal;">Lease Administration</strong>, <strong style="mso-bidi-font-weight: normal;">Project Management</strong>, <strong style="mso-bidi-font-weight: normal;">Space Management</strong> and <strong style="mso-bidi-font-weight: normal;">Maintenance Management</strong>.</em></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">Premiertec have decided to place strategic focus on delivering the IWMS solution to market. They have therefore designed and delivered an IWMS solution which is built on the latest Oracle E-Business Suite R12.1 platform. This incorporates integration between the following modules -<span style="mso-spacerun: yes;"> </span>Oracle Property Manager, Oracle Projects, Oracle Enterprise Asset Management, Oracle Site Hub, Oracle Service and Oracle Financials applications. Known as the <strong style="mso-bidi-font-weight: normal;">Premiertec Integrated Workplace Management System</strong> (PIWMS), this solution supports the entire real estate lifecycle through a complete, end-to-end Real Estate Management solution. </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 10pt; line-height: 14.25pt;"><span style="font-size: 12pt; color: black; mso-ascii-font-family: Calibri; mso-fareast-font-family: 'Times New Roman'; mso-hansi-font-family: Calibri; mso-bidi-font-family: 'Times New Roman'; mso-fareast-language: EN-GB;">George Gallant - March 2010</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/what-is-iwms/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tale of one deployment</title>
		<link>http://www.premiertec.com/blog/tale-of-one-deployment/</link>
		<comments>http://www.premiertec.com/blog/tale-of-one-deployment/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 16:00:31 +0000</pubDate>
		<dc:creator>Miroslav Samoilenko</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Fusion]]></category>

		<category><![CDATA[ADF]]></category>

		<category><![CDATA[Deployment]]></category>

		<category><![CDATA[WebLogic]]></category>

		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=113</guid>
		<description><![CDATA[Recently we built a killer ADF Fusion application for one of our customers. The solution was built on time using JDeveloper 11g build 5536 (version important). We tested deployment on the integrated WebLogic server on one our Windows XP Pro laptops, deployed test WebLogic 10.3 server on Windows 2003 machine, installed matching ADF Runtime libraries [...]]]></description>
			<content:encoded><![CDATA[<p>Recently we built a killer ADF Fusion application for one of our customers. The solution was built on time using JDeveloper 11g build 5536 (version important). We tested deployment on the integrated WebLogic server on one our Windows XP Pro laptops, deployed test WebLogic 10.3 server on Windows 2003 machine, installed matching ADF Runtime libraries and were in eager anticipation to see our creation run in a production-like environment.</p>
<p>Little did we know&#8230;<span id="more-113"></span></p>
<p>The first crises happened when during deployment WebLogic could not find class oracle.adf.share.weblogic.listeners.ADFApplicationLifecycleListener. Thanks to  this <a href="http://forums.oracle.com/forums/thread.jspa?threadID=837936">note </a> we realized that we need to open EAR and comment the listener. And then listeners JpsAppVersionLifecycleListener and JpsApplicationLifecycleListener met the same finale thanks to the <a href="http://forums.oracle.com/forums/thread.jspa?messageID=3186228">note </a>. And finally, listener WLLifecycleListener was removed from EAR. With all those removals, the application was tested on the integrated WebLogic Server.</p>
<p>Finally, WebLogic deployer said that application is successfully deployed. Phew&#8230; If you think this is it, then listen to this.</p>
<p>We try to access the application. Application, definitely, fails complaining that we provided NULL password for the database. That was a surprise. You cannot define a data source without specifying password to the database schema. We found a note that we need to add certain parameters to JAVA_PROPERTIES in the setDomainEnv.cmd file. It worked on Windows XP, and did not work on Windows 2003. So, the solution was to change how Application Modules reference the database connection. We switched from JDBC URL to JDBC Data Source.</p>
<p>We access the first page of our application which contains both charts and non-graphical elements. Non-graphical elements rendered ok. BINGO!!!! But all charts failed&#8230; The log files provided a very interesting error. It was looking for a data source with name jdbc.NAMEDS instead of jdbc/NAMEDS. So, we had to create an additional data source with JNDI name jdbc.NAMEDS. </p>
<p>Finally it worked. It took us a week to figure out all these steps to understand how to deploy the application. I still do not feel comfortable with removal of the listeners. There must be a way to plug in libraries into the setDomainEnd.cmd file for the libraries to be seen.</p>
<p>Our next task is to connect to our applciation via an OCI driver. Stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/tale-of-one-deployment/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Why does offshore produce such a bad code?</title>
		<link>http://www.premiertec.com/blog/why-does-offshore-produce-such-a-bad-code/</link>
		<comments>http://www.premiertec.com/blog/why-does-offshore-produce-such-a-bad-code/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 01:38:30 +0000</pubDate>
		<dc:creator>Miroslav Samoilenko</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Offshore Management]]></category>

		<category><![CDATA[Project Tracking]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=106</guid>
		<description><![CDATA[Recently a good friend of mine asked me 
Why does offshore produce such a bad code?
This is not the first time I was asked this question, not to mention myself asking this question. I knew the answer for this question for the last several years, but I did not know how to make change it. [...]]]></description>
			<content:encoded><![CDATA[<p>Recently a good friend of mine asked me </p>
<blockquote><p>Why does offshore produce such a bad code?</p></blockquote>
<p>This is not the first time I was asked this question, not to mention myself asking this question. I knew the answer for this question for the last several years, but I did not know how to make change it. </p>
<p>These are my findings.<span id="more-106"></span></p>
<p>Most of big consulting companies which I worked with, which includes (call me if you need company names) among others, impose offshore developers onto the project. It means that if you are an on-site technical manager you are given the offshore developers. You are not allowed to screen resumes of developers or pick the developer you want. People are given to you. No wonder they are referred to as ‘resources’; a blind headcount to meet the project plant requirement for full time employees. I do not want to say that individual developers are bad; however, I have a handful of jokes about the questions I was asked by offshore developers whom I asked to be ultimately removed from the project. Even though offshore developers are ‘cheap’ per hour, a non-qualified offshore developer can cost the customer a lot of money via late code deliveries and poor code quality.</p>
<p>For the second reason I will use the same cliché. Most of big consulting companies, which is probably better versed as, most offshore development managers wish to present their development unit as a black box. You throw a functional design onto them, they tell when it will be built and tested and… offshore vanishes into thin air. Any request as to the progress comes back as ‘WIP’. Any code check in the database returns empty results because the offshore development manager claims that they have a local copy of the database. The delivery date comes and goes, and a couple of days later the offshore development manager presents you with something that is claimed to be fully tested code written according to the specification. The reality is… well… we need to start the real build now.</p>
<p>I am sure the story is familiar to many onsite technical managers. It fully describes ‘Why’ offshore development is difficult. The true question is how to make it work.</p>
<p>I happen to work with an offshore model for one of our European customers where I was perceived as an offshore developer (I live in USA). This is the approach I tried to implement which proved to work quite well. A functional consultant throws a functional design to me and I give back the dates when I think the code will be ready. I write the technical design and post it to the central storage for reviews. Then I start coding. This is a quiet time that lasts several days. However, as soon as I have a piece of code that somehow meets the requirements of the functional design, I claim to the functional consultant that code is written. How much time have I spent?.. Maybe 25% of the time allocated to development. The next week or two (depending on the complexity of the design) are nightmare. Functional designer logs one defect after another, even basic tests break, I am called all kind of names… I keep my head down and keep on coding. One week passes, and tests start completing as desired. Functional consultant finds bits and pieces which he/she overlooked and I add it to the code. By the time the time allocated for coding and functional testing passed, the code is in perfect stage, functional consultant is happy with results, and I am being petted on my shoulder for delivering high quality code on time.</p>
<p>This approach does require a level of maturity from both developer and tester. One of the most difficult parts is that bugs, or defects, are natural part of a software development. This is not evil, this is good. This is something which drives average software to perfection. I am always saying that if not a single defect is caught during the first test, then the defect is so deep in the code that it will take many tests to uncover. It also requires a level of patience on the tester’s side as well as understanding that the first cut of software is very raw. So raw that even the developer did not run a single full test scenario. However, from the customer stand point, such approach delivers the solution on time and with quality.</p>
<p>We, at Premiertec, apply this approach not only to Oracle eBusiness Suite projects. Even on short term engagements, like an Oracle ADF custom development project which ran for just over a month, we did bi-weekly customer presentations of the solution not to mention daily code checks and numerous internal demos. This was a remarkable project where the customer was in the United Kingdom, solution architect in USA, and the development team in our near-shore development center in Ukraine.</p>
<p>This was my answer to the question my good friend asked me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/why-does-offshore-produce-such-a-bad-code/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Location, Location, Location. Part 2.</title>
		<link>http://www.premiertec.com/blog/location-location-location-part-2/</link>
		<comments>http://www.premiertec.com/blog/location-location-location-part-2/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 17:25:05 +0000</pubDate>
		<dc:creator>Miroslav Samoilenko</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[concurrent program]]></category>

		<category><![CDATA[oe_sys_parameters_util]]></category>

		<category><![CDATA[value set]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=103</guid>
		<description><![CDATA[While building a report, I was asked to print report title that matches the name of the concurrent program, date the report was executed, and the only report paremeter with its meaning.
The title of the report and execution date is simple. The parameter reads its values from an independent value set. So, I started to [...]]]></description>
			<content:encoded><![CDATA[<p>While building a report, I was asked to print report title that matches the name of the concurrent program, date the report was executed, and the only report paremeter with its meaning.</p>
<p>The title of the report and execution date is simple. The parameter reads its values from an independent value set. So, I started to think how to get hold of the value set ID and what table do I need to read for the meaning, etc. And then!!! I recollected my own blog.</p>
<p>The resulting query is here without much explanations.</p>
<blockquote><p>select fcr.actual_start_date report_start_date<br />
, fcp.user_concurrent_program_name<br />
, fu.user_name submitted_by<br />
, fcr.argument1 parameter_code<br />
, oe_sys_parameters_util.get_value(fdfcu.flex_value_set_id, fcr.argument1) parameter_description<br />
from fnd_concurrent_requests fcr<br />
, fnd_concurrent_programs_vl fcp<br />
, fnd_user fu<br />
, FND_DESCR_FLEX_COL_USAGE_VL fdfcu<br />
where fcr.concurrent_program_id = fcp.concurrent_program_id<br />
and fcr.requested_by = fu.user_id<br />
and fdfcu.descriptive_flexfield_name = &#8216;$SRS$.&#8217;|| fcp.concurrent_program_name<br />
and fdfcu.application_column_name = &#8216;ATTRIBUTE1&#8242;<br />
and fcr.request_id = fnd_global.conc_request_id</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/location-location-location-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Connecting the dots</title>
		<link>http://www.premiertec.com/blog/connecting-the-dots/</link>
		<comments>http://www.premiertec.com/blog/connecting-the-dots/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 10:42:31 +0000</pubDate>
		<dc:creator>Miroslav Samoilenko</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[count dots]]></category>

		<category><![CDATA[replace]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=101</guid>
		<description><![CDATA[While doing research for the next release of Hermes, Premiertec’s flagship project management tool, I came across a task where I had to parse a string like
apps.xxpt_chain_controller_pkg.execute
into procedure name, package name and optional schema name. To achieve this I had to count the number of dots in the string.
Being naturally lazy, I decided to give [...]]]></description>
			<content:encoded><![CDATA[<p>While doing research for the next release of Hermes, Premiertec’s flagship project management tool, I came across a task where I had to parse a string like</p>
<blockquote><p>apps.xxpt_chain_controller_pkg.execute</p></blockquote>
<p>into procedure name, package name and optional schema name. To achieve this I had to count the number of dots in the string.</p>
<p>Being naturally lazy, I decided to give Internet a spin and find a ready answer. To my dismay, all the ready-to-go answers were PL/SQL procedures of questionable quality. The ingenuity of developers did not go beyond reading the string symbol by symbol and, literally, counting dots.</p>
<p>If you are interviewing a PL/SQL developer, please, use this example as an interview question with the proper answer as</p>
<blockquote><p>select length(p_string) – length(replace(p_string, &#8216;.&#8217;)) from dual</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/connecting-the-dots/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Uploading Excel Spreadsheet into Oracle eBusiness Suite. Part 6.</title>
		<link>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-6/</link>
		<comments>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-6/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 19:10:29 +0000</pubDate>
		<dc:creator>Miroslav Samoilenko</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Fusion]]></category>

		<category><![CDATA[Oracle]]></category>

		<category><![CDATA[R12]]></category>

		<category><![CDATA[Java Concurrent Program]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=84</guid>
		<description><![CDATA[Writing Java Concurrent Program
Any Java class that implements interface oracle.apps.fnd.cp.request.JavaConcurrentProgram can be registered as a concurrent program.
The only method which needs to be implemented is
public void runProgram(oracle.apps.fnd.cp.request.CpContext cpcontext)
CpContext provides developer with all attributes of a PL/SQL concurrent program such as output file, log file, and return status plus a database connection. A typical implementation of [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Writing Java Concurrent Program</strong><br />
Any Java class that implements interface oracle.apps.fnd.cp.request.JavaConcurrentProgram can be registered as a concurrent program.</p>
<p>The only method which needs to be implemented is</p>
<blockquote><p>public void runProgram(oracle.apps.fnd.cp.request.CpContext cpcontext)</p></blockquote>
<p>CpContext provides developer with all attributes of a PL/SQL concurrent program such as output file, log file, and return status plus a database connection. A typical implementation of this method looks like<span id="more-84"></span></p>
<blockquote><p>public void runProgram(CpContext cpcontext) {<br />
  try {<br />
    // read parameters<br />
    // execute business logic<br />
             cpcontext.getReqCompletion().setCompletion(ReqCompletion.NORMAL, &#8220;Request Completed Normal&#8221;);<br />
  } catch (Exception ex) {<br />
    // report exception<br />
    cpcontext.getReqCompletion().setCompletion(ReqCompletion.ERROR, &#8220;Error building output file&#8221;);<br />
  } finally {<br />
    cpcontext.releaseJDBCConnection();<br />
  }<br />
}</p></blockquote>
<p>Though this template is small, it does illustrate the key differences between Java and PL/SQL concurrent program.</p>
<p>By default, Java concurrent program completes with an error, unlike PL/SQL program which completes successfully. Hence, it is imperative to set up not only completion in error, but also when program completes successfully.</p>
<p>At the end of the execution of the Java concurrent program, you must release JDBC connection back to the pool.</p>
<p><strong>Reading Parameters</strong></p>
<p>Concurrent program parameters are accessible via method cpcontext. getParameterList. This method returns an instance of oracle.apps.fnd.util.ParameterList class. This class provides an Enumeration interface to access all the parameters passed to the program in the order defined during the concurrent program registration. This class has one interesting drawback. You can read the parameters only once.</p>
<p>Each concurrent program parameter is represented by an instance of class oracle.apps.fnd.util.NameValueType. It is clear from the name of the class that it provides name, type and string value of the parameter. It means that if you have a date value as the parameter to the concurrent program, it will be available to the Java concurrent program as a canonical string.</p>
<p>I found it useful to have a utility that converts the ParameterList into a Map.</p>
<blockquote><p>  static public Map convertParameters(ParameterList parameterList)<br />
  { Map result = new HashMap();<br />
    while( parameterList.hasMoreElements() ) {<br />
        NameValueType nameValueType = parameterList.nextParameter();</p>
<p>        if (nameValueType.getValue() != null)<br />
        {<br />
          result.put(nameValueType.getName(), nameValueType.getValue());<br />
        }<br />
      }<br />
    return result;<br />
  }</p></blockquote>
<p>Map provides a better controlled access to the list of parameters. The method can be enhanced to recognize the type of the value and convert them from String into BigDecimal or Date.</p>
<p><strong>Reporting Exception</strong></p>
<p>Exception.printStackTrace() does not work here!!!</p>
<p>If you really want the user to see the exception stack, you need to print it into the oracle.apps.fnd.cp.request.LogFile. An instance of this class is available via cpcontext.getLogFile().  This class provides an OutputStream like interface, though it is not an implementation of java.io.OutputStream.</p>
<p>LogFile provides a number of methods to write strings into the output stream like</p>
<blockquote><p>write(String message, int level)</p></blockquote>
<p>Here, level specifies the debugging level which can be set from LogFile.STATEMENT to LogFile.EXCEPTION.<br />
In order to report exception to the log file, you can use the following code</p>
<blockquote><p>        StringWriter writer = new StringWriter();<br />
        ex.printStackTrace(new PrintWriter(writer));<br />
        logFile.writeln(writer.toString(), logFile.EXCEPTION);</p></blockquote>
<p><strong>Writing Output</strong></p>
<p>The key task of the concurrent program which we are writing is to read the CLOB that contains the file contents and write it into its output stream. The output of a concurrent program can later be accessed by SQL*Loader, other concurrent program or, even, OAF web pages and services outside of Oracle eBusiness Suite.</p>
<p>To access the database, we need to get hold of the database connection. An instance of the connection can received from cpcontext.getJDBCConnection().</p>
<p>The following method retrieves the CLOB from the database as and InputStream which is then converted into a String.</p>
<blockquote><p>  protected String getOutput(Connection connection, BigDecimal primaryKey) throws SQLException, IOException<br />
  {<br />
    String statement = &#8220;select file_contents from xxpt_file_upload_tmp where id = :1&#8243;;<br />
    String result;<br />
    PreparedStatement stmt = null;<br />
    ResultSet resultSet = null;<br />
    try {<br />
     stmt = connection.prepareStatement(statement);<br />
     stmt.setBigDecimal(1, primaryKey);<br />
     resultSet = stmt.executeQuery();<br />
     resultSet.next();<br />
     result =streamToString( resultSet.getAsciiStream(1) );<br />
     resultSet.close();<br />
     resultSet = null;<br />
     stmt.close();<br />
     stmt = null;<br />
    } finally<br />
    {<br />
      if (resultSet != null)<br />
      {<br />
        try { resultSet.close(); } catch (SQLException ex) {}<br />
      }<br />
      if (stmt != null)<br />
      {<br />
        try { stmt.close(); } catch (SQLException ex) {}<br />
      }<br />
      try { connection.commit(); } catch (SQLException ex) {}<br />
    }<br />
    return result;<br />
  }</p></blockquote>
<p>In this code streamToString method read the InputStream into a String.</p>
<p>An instance of oracle.apps.fnd.cp.request.OutFile get be obtained using methof cpcontext.getOutFile(). This class provides OutputStream like interface, though it is not an implementation of java.io.OutputStream. Writing a string into the output is as simple as</p>
<blockquote><p>cpcontext.getOutFile().write(fileContents);</p></blockquote>
<p><strong>Submit Concurrent Program from Java</strong></p>
<p>Oracle provides Java classes to submit a concurrent program. Definitely, one can call PL/SQL procedure directly using JDBC connection, though the Java wrapper is much nicer and easier to use.</p>
<p>Class oracle.apps.fnd.cp.request.ConcurrentRequest represents submission of a concurrent request. You can setup optional layouts, notifications, schedule and other attributes available through FND_REQUEST package.</p>
<p>Constructor of ConcurrentRequest class accepts database connection instance as a parameter.<br />
Signature of the method that submits the concurrent request for execution</p>
<blockquote><p>submitRequest(String application, String program, String description, String startTime, String subrequest, Vector parameters)</p></blockquote>
<p>mimics parameters of the corresponding PL/SQL  procedure FND_REQUEST.SUBMIT_REQUEST. Here, parameters is the vector of String in the order the parameters are specified during the concurrent program registration. If one of your parameters is a Date, it is your responsibility to convert it into the canonical string.</p>
<p>So, the code that submits the concurrent program may look like</p>
<blockquote><p>  protected void submitConcurrentProgram(Number primaryKey, String purposeCode, int orgId, Connection connection) throws IOException, SQLException, RequestSubmissionException<br />
  {<br />
      ConcurrentRequest request = new ConcurrentRequest(connection);<br />
      Vector param = new Vector();<br />
      param.add(primaryKey.stringValue());<br />
      param.add(purposeCode);<br />
      param.add(String.valueOf(orgId));</p>
<p>      int reqId = request.submitRequest(&#8221;XXPT&#8221;, &#8220;XXPTCLOBOUTPUT&#8221;, &#8220;Print CLOB&#8221;,null, false, param);<br />
      connection.commit();</p>
<p>      MessageToken[] tokens = { new MessageToken(&#8221;REQUEST&#8221;, String.valueOf(reqId)) };<br />
      OAException confirmMessage = new OAException(&#8221;XXPT&#8221;,<br />
                                              &#8220;XXPT_REQUEST_SUBMIT_CONF&#8221;,<br />
                                              tokens,<br />
                                              OAException.CONFIRMATION,<br />
                                              null);<br />
      throw confirmMessage;<br />
  }</p></blockquote>
<p>As you can see, upon successful submission of the concurrent program, we raise a confirmation exception with the request ID.</p>
<p>This post concludes the series. In the course of six installments we learned the overall technical design, how to build OAF based UI to upload a file, how to parse an Excel spreadsheet into a comma delimited file, how to write a Java concurrent program and submit it from an OAF page controller. Everything I was talking about here has been built and is actively being used by our customers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-6/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Uploading Excel Spreadsheet into Oracle eBusiness Suite. Part 5.</title>
		<link>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-5/</link>
		<comments>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-5/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 10:59:13 +0000</pubDate>
		<dc:creator>Miroslav Samoilenko</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Fusion]]></category>

		<category><![CDATA[Oracle]]></category>

		<category><![CDATA[R12]]></category>

		<category><![CDATA[BC4J]]></category>

		<category><![CDATA[ClobDomain]]></category>

		<category><![CDATA[getAllRowsInRange]]></category>

		<category><![CDATA[setMaxFetchSize]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=81</guid>
		<description><![CDATA[Storing CLOB in database table
Once we have the input stream converted into an ASCII string, we need to store it in the custom table. To perform this operation, we need to generate primary key, and extract the purpose for the upload.
We already discussed the query which generated globally unique primary key, and creation of a [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Storing CLOB in database table</strong><br />
Once we have the input stream converted into an ASCII string, we need to store it in the custom table. To perform this operation, we need to generate primary key, and extract the purpose for the upload.</p>
<p>We already discussed the query which generated globally unique primary key, and creation of a view object PrimaryKeyGeneratorVO  based on this query. The method which generates the primary key becomes</p>
<blockquote><p>  protected Number generatePrimaryKey()<br />
  {<br />
    OAViewObject viewObject = getPrimaryKeyGeneratorVO();<br />
    viewObject.setMaxFetchSize(1);<br />
    viewObject.executeQuery();<br />
    return (Number) (viewObject.first().getAttribute(&#8221;Id&#8221;));<br />
  }</p></blockquote>
<p><span id="more-81"></span><br />
In order to determine the select purpose, we need to walk through each row of purposes in the current range, and locate the one with checked attribute ‘Selected’, since this was the transient attribute designated to work with table single selection. The method is</p>
<blockquote><p>  public String getSelectedPurpose()<br />
  {<br />
    OAViewObject viewObject = getFileUploadPurposeVO();<br />
    Row[] rows = viewObject.getAllRowsInRange();<br />
    if (rows.length > 0)<br />
    {<br />
      for(int i=0; i<rows.length; i++)<br />
      {<br />
        Row row = rows[i];<br />
        if ("Y".equals(row.getAttribute("Selected"))) {<br />
          return (String)row.getAttribute("LookupCode");<br />
        }<br />
      }<br />
    }<br />
    return null;<br />
  }</p></blockquote>
<p>Now, we are ready to store data in the database. We will need the purpose of the upload later when we submit the concurrent program to print the file contents in its output. So, we extract the purpose separately and pass as a parameter to the storage procedure, which now looks like</p>
<blockquote><p> public Number storeStream(String inputStream, String purposeCode)<br />
  {<br />
      OAViewObject viewObject = am.getXXPTFileUploadTmpVO();<br />
      viewObject.setMaxFetchSize(0);</p>
<p>      ClobDomain myClob = new ClobDomain();<br />
      myClob.setChars(inputStream.toCharArray());<br />
      OARow row = (OARow)viewObject.createRow();<br />
      row.setAttribute(&#8221;FileContents&#8221;,myClob);<br />
      Number primaryKey = generatePrimaryKey();<br />
      row.setAttribute(&#8221;PurposeCode&#8221;, purposeCode);<br />
      row.setAttribute(&#8221;Id&#8221;, primaryKey);<br />
      viewObject.insertRow(row);<br />
      am.getTransaction().commit();<br />
      return primaryKey;<br />
  }</p></blockquote>
<p>The method returns the primary key of the newly created record. We will later pass this key to the concurrent program that prints the output of the CLOB into its output.</p>
<p>Stay with us to learn how to write Java concurrent programs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-5/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Uploading Excel Spreadsheet into Oracle eBusiness Suite. Part 4.</title>
		<link>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-4/</link>
		<comments>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-4/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 11:26:00 +0000</pubDate>
		<dc:creator>Miroslav Samoilenko</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Fusion]]></category>

		<category><![CDATA[Oracle]]></category>

		<category><![CDATA[R12]]></category>

		<category><![CDATA[CSV]]></category>

		<category><![CDATA[Excel]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[JExcelAPI]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=78</guid>
		<description><![CDATA[Converting Excel to CSV
There are several open source and commercial Java libraries that are capable of reading Excel workbooks. Among those are Apache POI , JExcelAPI, JCom, ExtenXLS7 to name a few. We will use JExcelAPI to recognize and process Excel files.
We assume that users are loading either Excel workbooks or ASCII files, such as [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Converting Excel to CSV</strong><br />
There are several open source and commercial Java libraries that are capable of reading Excel workbooks. Among those are <a href="http://poi.apache.org/">Apache POI </a>, <a href="http://jexcelapi.sourceforge.net/">JExcelAPI</a>, <a href="http://sourceforge.net/projects/jcom/">JCom</a>, <a href="http://www.extentech.com/estore/product_detail.jsp?product_group_id=1">ExtenXLS7</a> to name a few. We will use JExcelAPI to recognize and process Excel files.<span id="more-78"></span></p>
<p>We assume that users are loading either Excel workbooks or ASCII files, such as XML documents or CSV files. This makes streamToString method looks like this.</p>
<blockquote><p>  protected String streamToString(String mimeType, InputStream inputStream) throws IOException<br />
  {<br />
    String result;<br />
	// check if this is an Excel spreadsheet<br />
    if (&#8221;application/vnd.ms-excel&#8221;.equalsIgnoreCase(mimeType))<br />
    {<br />
      try {<br />
        result = xlsToString(inputStream);<br />
      } catch (jxl.read.biff.BiffException ex)<br />
      { // if not, then assume this is an ASCII stream<br />
        inputStream.reset();<br />
        result = streamToString(inputStream);<br />
      }<br />
    } else<br />
    { // otherwise an ASCII stream<br />
      result = streamToString(inputStream);<br />
    }<br />
    return result;<br />
  }</p></blockquote>
<p>This method interprets the mimeType of the inbound file, and either reads it as an Excel workbook using method xlsToString(InputStream) or converts it into a string using method streamToString(InputStream). We will omit details of streamToStream(InputStream) method, as it reads characters from the input stream and appends them to a string, and concentrate on xlsToString(InputStream).</p>
<p>The body for this method was borrowed from <a href="http://www.java-tips.org/other-api-tips/jexcel/converting-excel-documents-to-csv-files.html">here</a>. The method interprets the input stream as an Excel workbook and converts each sheet into a comma separated format.</p>
<blockquote><p>private final static String CSV_SEPARATOR = &#8220;,&#8221;;</p>
<p>private String xlsToString(InputStream stream) throws jxl.read.biff.BiffException<br />
  {<br />
    StringWriter stringWriter = new StringWriter();<br />
    BufferedWriter bufferedWriter = new BufferedWriter(stringWriter);<br />
    try {<br />
      WorkbookSettings ws = new WorkbookSettings();<br />
      ws.setLocale(new Locale(&#8221;en&#8221;, &#8220;EN&#8221;));<br />
      Workbook w = Workbook.getWorkbook(stream, ws);</p>
<p>      // Gets the sheets from workbook<br />
      for (int sheet = 0; sheet < w.getNumberOfSheets(); sheet++)<br />
      {<br />
        Sheet s = w.getSheet(sheet);<br />
        Cell[] row = null;</p>
<p>        // Gets the cells from sheet<br />
        for (int i = 0 ; i < s.getRows() ; i++)<br />
        {<br />
          row = s.getRow(i);<br />
          if (row.length > 0)<br />
          {<br />
            bufferedWriter.write(formatExcelCell(row[0]));<br />
            for (int j = 1; j < row.length; j++)<br />
            {<br />
              bufferedWriter.write(CSV_SEPARATOR);<br />
              bufferedWriter.write(formatExcelCell(row[j]));<br />
            }<br />
          }<br />
          bufferedWriter.newLine();<br />
        }<br />
      }<br />
      bufferedWriter.flush();<br />
    } catch(jxl.read.biff.BiffException ex)<br />
    {<br />
      throw ex;<br />
    }<br />
    catch (Exception ex)<br />
    {<br />
      throw OAException.wrapperException(ex);<br />
    }</p>
<p>    return stringWriter.toString();<br />
  }</p></blockquote>
<p>Method formatExcelCell is responsible for converting the contents of a cell into the one compatible with CSV file format. Namely</p>
<ul>
<li>double each double quote</li>
<li>surround contents with double quotes if contents contains a double quote or comma</li>
<li>convert date into DD-MMM-YYYY format</li>
</ul>
<p>The formatExcelCell method body is</p>
<blockquote><p>
    private final static String QUOTE_STRING = &#8220;&#8221;";<br />
    private SimpleDateFormat dateFormatter = new SimpleDateFormat(&#8221;d-MMM-yyyy&#8221;);</p>
<p>  private String formatExcelCell(Cell cell)<br />
  {<br />
    if (cell == null) return null;<br />
    String rowCell = cell.getContents();<br />
    // format the date<br />
    if ( cell.getType().equals(cell.getType().DATE) )<br />
    {<br />
      rowCell = dateFormatter.format(((DateCell)cell).getDate());<br />
    }<br />
    // double each quote<br />
    String result = rowCell.replaceAll(QUOTE_STRING, QUOTE_STRING+QUOTE_STRING);<br />
    // surround with quotes if comma or quote is present<br />
    if (result.indexOf(CSV_SEPARATOR) >0 || result.indexOf(QUOTE_STRING) >0)<br />
    {<br />
      result = QUOTE_STRING + result + QUOTE_STRING;<br />
    }<br />
    return result;<br />
  }</p></blockquote>
<p>Here we reached the point when the incoming stream is tested to be an Excel workbook, and if so, converted into a comma separate stream. Otherwise, it is assumed that the incoming file is an ASCII stream.</p>
<p>Our next task is to store the contents in the database. Stay tuned to learn how to write CLOBs using BC4J.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-4/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Uploading Excel Spreadsheet into Oracle eBusiness Suite. Part 3.</title>
		<link>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-3/</link>
		<comments>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-3/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 12:47:45 +0000</pubDate>
		<dc:creator>Miroslav Samoilenko</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Fusion]]></category>

		<category><![CDATA[Oracle]]></category>

		<category><![CDATA[R12]]></category>

		<category><![CDATA[fileUploadItem]]></category>

		<category><![CDATA[OAF]]></category>

		<category><![CDATA[OAPageContext]]></category>

		<category><![CDATA[UPLOAD_FILE_MIME_TYPE]]></category>

		<category><![CDATA[UPLOAD_FILE_NAME]]></category>

		<guid isPermaLink="false">http://www.premiertec.com/blog/?p=74</guid>
		<description><![CDATA[Building UI
First of all, we need to define business objects and explain their usage. The page we are building contains one field on top of the page where the user specifies the file to upload, and then a table below where user select the purpose for the upload.
The content for the table comes from a [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Building UI</strong><br />
First of all, we need to define business objects and explain their usage. The page we are building contains one field on top of the page where the user specifies the file to upload, and then a table below where user select the purpose for the upload.<span id="more-74"></span></p>
<p>The content for the table comes from a view object FileUploadPurposeVO which is sourced by the query from the technical design. We add to it a transient updatable attribute ‘Selected’ to allow for single table selection.</p>
<p>The content of the uploaded file is stored in the database table XXPT_FILE_UPLOAD_TMP. So, we create an entity object XXPTFileUploadTmpEO and corresponding view object XXPTFileUploadTmpVO.</p>
<p>We also need a primary key generator. The first thought, of course, is to define a custom sequence. I do not like this idea since the primary key here does not need to be sequential; it just needs to be unique. So, the sequence will be an extra custom database object without a very good need. We can also define or reuse a document sequence. However, this is a lot of application setups for a primary key which will live only a couple of seconds. </p>
<p>The approach I prefer is to use the GUID generated by the database and convert it into a number. The following query generates unique number each run you execute it. </p>
<blockquote><p>select okc_p_util.raw_to_number(sys_guid()) id from dual</p></blockquote>
<p>We build a view object PrimaryKeyGeneratorVO based on this query. This view object completes our data model.</p>
<p>There are many examples available over the internet and in the Developer’s Guide on how to build an OAF page. We will skip those here. The relevant assumption is that the table which displays the upload purposes is a single selection table with an action button ‘submitButton’.</p>
<p>This makes the page controller entry point look like this</p>
<blockquote><p>  /**<br />
   * Procedure to handle form submissions for form elements in<br />
   * a region.<br />
   * @param pageContext the current OA page context<br />
   * @param webBean the web bean corresponding to the region<br />
   */<br />
  public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)<br />
  {<br />
    super.processFormRequest(pageContext, webBean);<br />
    OAApplicationModule am = pageContext.getApplicationModule(webBean);</p>
<p>    if (pageContext.getParameter(&#8221;submitButton&#8221;) != null)<br />
    { processFileUpload(pageContext, webBean, am);<br />
    }<br />
  }</p></blockquote>
<p>Method processFileUpload is performing the following tasks</p>
<ul>
<li>get hold of the binary file contents</li>
<li>convert binary file contents into an ASCII stream</li>
<li>store ASCII in the file in the database</li>
<li>submit the printing request</li>
</ul>
<p>The body of this method is</p>
<blockquote><p>protected void processFileUpload(OAPageContext pageContext, OAWebBean webBean, OAApplicationModule am)<br />
  {</p>
<p>    // Get hold of the binary file contents<br />
    DataObject fileUploadData = (DataObject)pageContext.getNamedDataObject(&#8221;fileUploadItem&#8221;);<br />
    if (fileUploadData == null) return;</p>
<p>    String fileName = (String)fileUploadData.selectValue(null, &#8220;UPLOAD_FILE_NAME&#8221;);<br />
    if (fileName == null) return;</p>
<p>    String contentType =(String)fileUploadData.selectValue(null, &#8220;UPLOAD_FILE_MIME_TYPE&#8221;);</p>
<p>    BlobDomain uploadedByteStream = (BlobDomain)fileUploadData.selectValue(null, fileName);<br />
    if (uploadedByteStream == null) return;</p>
<p>    // convert binary file contents into an ASCII stream<br />
    try {<br />
      String inputStream = streamToString(contentType, uploadedByteStream.getInputStream() );  </p>
<p>      String purposeCode = getSelectedPurpose(am);<br />
      if (purposeCode == null)<br />
      {<br />
        throw new OAException(&#8221;XXRFG&#8221;,<br />
                              &#8220;XXRFG_SCR0248_MISSING_PURPOSE&#8221;,<br />
                              null,<br />
                              OAException.ERROR,<br />
                              null);<br />
      }</p>
<p>      // Store ASCII in the file in the database<br />
      Number primaryKey = storeStream(inputStream , purposeCode, (UploadAMImpl)am);</p>
<p>      int orgId = ((OADBTransactionImpl)am.getOADBTransaction()).getOrgId();<br />
      // submit the printing request<br />
      submitConcurrentProgram(primaryKey, purposeCode, orgId, am.getOADBTransaction().getJdbcConnection());</p>
<p>    } catch (IOException ex) {<br />
      throw OAException.wrapperException(ex);<br />
    } catch (SQLException ex) {<br />
      throw OAException.wrapperException(ex);<br />
    } catch (RequestSubmissionException ex) {<br />
      throw OAException.wrapperException(ex);<br />
    }<br />
  }</p></blockquote>
<p>Stay tuned to go into each of the methods&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.premiertec.com/blog/uploading-excel-spreadsheet-into-oracle-ebusiness-suite-part-3/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
