Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-useful-maven-plugins-part-1
Packt
09 Nov 2009
13 min read
Save for later

Useful Maven Plugins: Part 1

Packt
09 Nov 2009
13 min read
Nobody can tell exactly how many Maven plugins exist today—since, like dependencies they can be retrieved from any specified remote repository, there are likely hundreds to choose from, and likely even more that have been custom written for use within the infrastructure of particular organizations. A common practice for frameworks and tools that require build integration is to publish a Maven plugin to accomplish the task—and it is becoming increasingly common to encounter this as a standard part of the getting started section of a project you might hope to use. However, there are also a number of plugins that would be considered general purpose and handle some extended build cases in a wider variety of projects. While this won't come close to covering all the plugins you are likely to encounter, with these common tools in your arsenal it will cover many of your Maven build needs, reducing the need for you to write your own plugins. The Remote Resources plugin Most projects will use the Resources plugin at some point, even if it isn't configured directly—it is standard in the default life cycle for any packaging that produces some type of artifact, bundling the resources found in src/main/resources. However, what if you wanted to share those resources among multiple projects? The best approach to doing that is to store the resources in the repository and retrieve them for use in multiple builds—and that is where the Remote Resources plugin comes in. First, we should note that this is not the only alternative for handling the scenario. The Dependency plugin's unpack goal is also quite capable of unpacking an artifact full of resources directly into the location that will be packaged. However, the Remote Resources plugin offers several advantages: Re-integration with the resources life cycle so that retrieved resources will automatically be processed in any goals in the process-resources phase. The ability to perform additional processing on the resources (including the optional use of Velocity templates to generate the resources) before inclusion. A specific bundle generation goal for creating the resource artifact in the first place. These advantages can make the plugin very effective at dealing with some common scenarios. For example the inspiration for the creation of the plugin, and one of its more common uses, is to place aggregated license files within the final artifact. There are other scenarios where the dependency:unpack goal remains more suitable. It is best to select the Remote Resources plugin when the files will be incorporated into the resources life cycle and the Dependency plugin when the files will be utilized independently. Let's look at how to create a license file for our Centrepoint application. We will do this in two steps—the creation of the resource bundle that provides the generic resources for any project by the same organization, and the processing of the module resources. Creating a Remote Resource bundle Remote Resource bundles are regular JAR files packaged with additional information generated by the remote resource plugin's bundle goal. Creating a module follows the same process as with other JAR files. In the example application, we will create the module outside of the Centrepoint multi-module hierarchy, so that it could (theoretically) be used by other projects from the same organization. This could be anywhere in source control, but we will assume it sits side-by-side with the effectivemaven-parent module in the workspace. $ mvn archetype:generate -DartifactId=license-resources -DgroupId=com.effectivemaven As this is not going to be a code project, the src/main/java and src/test directories can be removed from the generated content. We then continue to add the parent project to the POM, so the result looks like the following: <project xsi_schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.effectivemaven</groupId> <artifactId>effectivemaven-parent</artifactId> <version>1-SNAPSHOT</version> <relativePath>../effectivemaven-parent/pom.xml</relativePath> </parent> <artifactId>license-resources</artifactId> <version>1.0-SNAPSHOT</version> <name>License Resource Bundle</name> </project> We will add the Remote Resources plugin shortly, but first let's create the resources that will be bundled. These are added to the src/main/resources like regular resources. Consider the following Velocity template file, src/main/resources/LICENSE.vm: ## License Generator #macro(showUrl $url) #if($url) ($url) #end #end This software is distributed under the following license(s): #foreach ($l in $project.licenses) - $l.name #showUrl ($l.url) #end #if (!$projectsSortedByOrganization.isEmpty()) The software relies on a number of dependencies. The individual licenses are outlined below. #set ($keys = $projectsSortedByOrganization.keySet()) #foreach ($o in $keys) From: '$o.name' #showUrl($o.url) #set ($projects = $projectsSortedByOrganization.get($o)) #foreach ($p in $projects) - $p.name #showUrl ($p.url) $p.artifact #foreach ($l in $p.licenses) License: $l.name #showUrl ($l.url) #end #end #end #end For those not familiar with Velocity, the purpose of this is to first iterate through the project's licenses and list them, then secondly iterate through the project's dependencies (grouped by the organization they are from) and list their license. The $projectsSortedByOrganization variable is a special one added by the Remote Resources plugin to assist in this task. Before we can move on to use the bundle, we need to add the plugin to the bundle project like so: <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-remote-resources-plugin</artifactId> <version>1.0</version> <executions> <execution> <goals> <goal>bundle</goal> </goals> </execution> </executions> </plugin> </plugins> </build> This goal is required to generate a bundle manifest, the contents of which tell the plugin which resources to process when it is later called on to do so. With this all in place, we can now install the bundle into the local repository, ready for use: license-resources$ mvn install If you were to inspect the contents of the generated JAR file, you would see both the LICENSE.vm file in the root, and the bundle manifest in META-INF/maven/remoteresources.xml. You would also find that the Velocity template is unmodified—the contents will be executed when the bundle is later processed in the target project, which we will proceed to look at now. Processing Remote Resources in a project Using the resource bundle we have created is now quite straightforward. We start by adding the folllowing to the build section of modules/pom.xml file of Centrepoint: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-remote-resources-plugin</artifactId> <version>1.0</version> <executions> <execution> <goals> <goal>process</goal> </goals> </execution> </executions> <configuration> <resourceBundles> <resourceBundle> com.effectivemaven:license-resources:1.0-SNAPSHOT </resourceBundle> </resourceBundles> </configuration> </plugin>   Here we have added a list of resource bundle artifacts to the configuration for the process goal, in the familiar shorthand artifact notation of groupId:artifactId:version. It has been added to the modules POM so that the license is included in the JAR files, but not included in the other non-code modules such as the documentation (which already generates a copy of the license from the reporting plugins). Normally, you should use a released version of the license bundle, not a snapshot as we have here (as we have not yet covered the release process!). Since the bundle is configured directly and not through a dependency, the Release plugin will not detect this unresolved snapshot later. Now, if we build a module such as store-api, we will see the license included in the root directory of the JAR file with the following content: This software is distributed under the following license(s): - The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt) The software relies on a number of dependencies. The individual licenses are outlined below. From: 'Apache Maven 2: Effective Implementations Book' (http://www.effectivemaven.com/) - Centrepoint Data Model com.effectivemaven.centrepoint:model:jar:1.0-SNAPSHOT License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt) From: 'Google' (http://www.google.com/) - Guice (http://code.google.com/p/google-guice/) com.google.code.guice:guice:pom:1.0 License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt) This is a good start, but we don't really need to include our own artifacts in the list, so we go back to the plugin declaration in modules/pom.xml and add another line of configuration: <configuration> <excludeGroupIds>${project.groupId}</excludeGroupIds> <resourceBundles> ... Regenerating the above artifact will alter the license to remove the dependencies from the project's group. A different case is the final distribution. As this is not part of the modules hierarchy, first we need to include the plugin definition identical to the one added previously. In the sample code for this article, you will notice that this has been taken a step further with the version and common configuration pushed into a pluginManagement section of the Centrepoint parent POM, and just the execution of the plugin goal remains in the modules and distribution POM files. We can now build the assembly as usual: distribution$ mvn clean install Upon inspecting the generated assemblies, you will not see the license file included yet. This is because the Assembly plugin does not pick up Maven resources by default, as it does not participate in the normal life cycle. To include the license file, we must alter the assembly descriptor distribution/src/main/assembly/bin.xml and add the following file set: <fileSet> <directory>target/maven-shared-archive-resources</directory> <outputDirectory>/</outputDirectory> </fileSet> The directory given is the standard location in which the Remote Resources plugin stores the resources it has processed, so if you decide to configure that differently in your own projects you would need to change this to the corresponding location. Upon building the assembly again we will see that the license has been generated, and that it includes the licenses of dependencies outside of the Centepoint application. As you can see, the distributed application depends on Jetty (also under the Apache License 2.0), which includes some portions of Glassfish (under the CDDL 1.0 License). While the above technique can be very helpful in constructing some useful information about your project and its dependencies, it cannot be guaranteed to produce complete licensing information for a project. The method relies on accurate information in the POMs of your dependencies, and this can sometimes be inaccurate (particularly when using public repositories such as the Maven Central Repository). If you are redistributing your files, always confirm that you have correctly recorded any necessary licensing information that must accompany them! The Remote Resources plugin is also capable of covering other scenarios that are particularly suited to license handling or more generally recording information about the project it is being processed for. These include: The supplementalDataModels configuration option that allows you to fill in incomplete or incorrect metadata for a project dependency before the resources are processed (to avoid particular problems as described above). The appendedResourcesDirectory, which allows you to store the above models in a separate file. The properties configuration, which allows the injection of other build properties into the Velocity templates. However, with this in mind, remember that the Remote Resources plugin is often just as suitable for any type of reusable resource, even if it is a static file. The Build Number plugin In Maven Mojos, the goals within a plugin are always designed to be simple tasks. Their aim is to do one thing, and do it well. A good example of this is the Build Number plugin. This simple plugin has one goal (create), with one purpose—to obtain a suitable build number and expose it to the build through properties or a file. While the plugin focuses on exposing the current Subversion revision, it is capable of generating an incremented build number (stored in a specified properties file), and a representation of the current system date and time. This feature can be very useful in identifying the exact heritage of a particular build. The build number generated by the plugin is different to that used by Maven to identify snapshots or artifact versions. While it is possible that you might mark your version using the information it generates, this plugin is typically used to record information about a particular build—whether it is a snapshot, or a release—within the artifact itself as a permanent record. Using the plugin is straightforward. By adding the goal to the project, the Subversion revision and a timestamp property will be exposed from the point that it is run onwards. <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> <version>1.0-beta-1</version> <executions> <execution> <phase>generate-resources</phase> <goals> <goal>create</goal> </goals> </execution> </executions> </plugin> In this example, we execute the plugin in the generate-resources phase so that the properties are available to any resource processing. Note that the values could be used with the Remote Resources plugin that we have just seen. There are two things to take into consideration with this configuration, however. Firstly, not all source builds will be Subversion checkouts, but the plugin does not verify that. To work around this potential problem, you can put the goal into a profile: <profile> <id>buildnumber</id> <activation> <file> <exists>.svn</exists> </file> </activation> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> ... This particular activation check will cause the profile to be used within a Subversion checkout (that is, if .svn exists in the current directory), and to skip the plugin if not. In this case, the properties will not be set (or the file will not be created), so the code using these must take that into account. Secondly, how the values will be accessed needs to be given careful consideration. For example, it is unlikely that you want to create a convoluted build processing step to filter the value into a particular JSP file to appear in a web application. For the sake of keeping the build simple (and speedy), it is best to write the values into a single file that the application can then load from its classpath. This can be achieved by creating a filtered resource that contains references to the values. The advantage of this method is that it is automatic if you have already configured filtered resources, and automatically ends up in the classpath of the application code that can load the file as a resource.
Read more
  • 0
  • 0
  • 6649

article-image-including-charts-and-graphics-pentaho-reports-part-1
Packt
09 Nov 2009
8 min read
Save for later

Including Charts and Graphics in Pentaho Reports (Part 1)

Packt
09 Nov 2009
8 min read
Supported charts Pentaho Reporting relies on JFreeChart, an open source Java chart library, for charting visualization within reports. From within Report Designer, many chart types are supported. In the chart editor, two areas of properties appear when editing a chart. The first area of properties is related to chart rendering, and the second tabbed area of properties is related to the data that populates a chart. Following is the screenshot of the chart editor within Pentaho Report Designer: All chart types receive their data from three general types of datasets. The first type is known as a Category Dataset , where the dataset series and values are grouped by categories. A series is like a sub-group. If the exact category and series appear, the chart will sum the values into a single result. The following table is a simple example of a category dataset: Category Series Sale Price Store 1 Sales Cash $14 Store 1 Sales Credit $12 Store 2 Sales Cash $100 Store 2 Sales Credit $120 Pentaho Reporting builds a Category Dataset using the CategorySetDataCollector. Also available is the PivotCategorySetCollector, which pivots the category and series data. Collector classes implement Pentaho Reporting’s Function API. The second type of dataset is known as an XY Series Dataset, which is a two dimensional group of values that may be plotted in various forms. In this dataset, the series may be used to draw different lines, and so on. Here is a simple example of an XY series dataset : Series Cost of Goods (X) Sale Price (Y) Cash 10 14 Credit 11 12 Cash 92 100 Credit 105 120 Note that X is often referred to as the domain, and Y is referred to as the range. Pentaho Reporting builds an XY Series Dataset using the XYSeriesCollector. The XYZSeriesCollector also exists for three dimensional data. The third type of dataset is known as a Time Series Dataset , which is a two dimensional group of values that are plotted based on a time and date. The Time Series Dataset is more like an XY Series than a Category Dataset, as the time scale is displayed in a linear fashion with appropriate distances between the different time references. Time Series Sale Price May 05, 2009 11:05pm Cash $14 June 07, 2009 12:42pm Credit $12 June 14, 2009 4:20pm Cash $100 June 01, 2009 1:22pm Credit $120 Pentaho Reporting builds a Time Series Dataset using the TimeSeriesCollector. Common chart rendering properties Most charts share a common set of properties. The following properties are common across most charts. Any exceptions are mentioned as part of the specific chart type. Required Property Group Property name Description name The name of the chart object within the report. This is not displayed during rendering, but must be unique in the report. A default name is generated for each chart added to the report. data-source The dataset name for the chart, which is automatically populated with the name of the dataset in the Primary DataSource panel of the chart editor. no-data-message The message to display if no data is available to render the chart. Title Property Group Property name Description chart-title The title of the chart, which is rendered in the report. chart-title-field A field representing the chart title. title-font The chart title's font family, size, and style. Options Property Group Property name Description horizontal If set to True, the chart's X and Y axis are rotated horizontally. The default value is set to False. series-colors The color in which to render each series. The default for the first three series colors are red, blue, and green. General Property Group Property name Description 3-D If set to True, renders the chart in a 3D perspective. The default value is set to False. anti-alias If set to True, renders chart fonts as anti-aliased. The default value is set to True. bg-color Sets the background around the chart to the specified color. If not set, defaults to gray. bg-image Sets the background of the chart area to the specified image. If not set, the background of the chart area defaults to white. The chart area is the area within the axes of the chart. Supported image types include PNG, JPG, and GIF file formats. show-border If set to True, displays a border around the chart. The default value is set to True. border-color Sets the border to the specified color. If not set, defaults to black. plot-border If set to False, clears the default rendering value of the chart border. plot-bg-color Sets the plot background color to the specified color. If not set, defaults to white. plot-fg-alpha Sets the alpha value of the plot foreground colors relative to the plot background. The default value is set to 1.0. plot-bg-alpha Sets the alpha value of the plot background color relative to the chart background color. The default value is set to 1.0.   Legend Property Group Property name Description show-legend If set to True, displays the legend for the chart. The default value is set to False. location The location of the legend in relation to the chart, which may be set to top, bottom, left, or right. The default location is bottom. legend-border If set to True, renders a border around the legend. The default value is set to True. legend-font The type of Java font to render the legend labels in. legend-bg-color Sets the legend background color. If not set, defaults to white. legend-font-color Sets the legend font color. If not set, defaults to black. Advanced Property Group Property name Description dependencyLevel The dependency level field informs the reporting engine what order the chart should be executed in relation to other items in the report. This is useful if you are using special functions that may need to execute prior to generating the chart. The default value is set to 0. Negative values execute before 0, and positive values execute after 0.   Common category series rendering properties The following properties appear in charts that render category information: Options Property Group Property name Description stacked If set to True, the series values will appear layered on top of one another instead of being displayed relative to one another. stacked-percent If set to True, determines the percentages of each series, and renders the bar height based on those percentages. The property stacked must be set to True for this property to have an effect. General Property Group Property name Description gridlines If set to True, displays category grid lines. This value is set to True by default. X-Axis Property Group Property name Description label-rotation If set, adjusts the inline item label rotation value. The value should be specified in degrees. If not specified, labels are rendered horizontally. You must have show-labels set to true for this value to be relevant. date-format If the item value is a date, a Java date format string may be provided to format the date appropriately. Please see Java's SimpleDateFormat JavaDoc for formatting details. numeric-format If the item value is a decimal number, a Java decimal format string may be provided to format the number appropriately. Please see Java's DecimalFormat JavaDoc for formatting details. text-format The label format used for displaying category items within the chart. This property is required if you would like to display the category item values. The following parameters may be defined in the format string to access details of the item: {0}: To access the Series Name detail of an item {1}: To access the Category detail of an item {2}: To access the Item value details of an item To display just the item value, set the format string to "{2}". x-axis-title If set, displays a label describing the category axis. show-labels If set to true, displays x-axis labels in the chart. x-axis-label-width Sets the maximum category label width ratio, which determines the maximum length each category label should render in. This might be useful if you have really long category names. x-axis-label-rotation If set, adjusts the category item label rotation value. The value should be specified in degrees. If not specified, labels are rendered horizontally. x-font The font to render the category axis title and labels in. Y-Axis Property Group Property name Description y-axis-title If set, displays a label along the value axis of the chart. label-rotation If set, determines the upward angle position of the label, where the value passed into JFreeChart is the mathematical pie over the value. Unfortunately, this property is not very flexible and you may find it difficult to use. y-tick-interval The numeric interval value to separate range ticks in the chart. y-font The font to render the range axis title in. y-sticky-0 If the range includes zero in the axis, making it sticky will force truncation of the axis to zero if set to True. The default value of this property is True. y-incl-0 If set to True, the range axis will force zero to be included in the axis. y-min The minimum value to render in the range axis. y-max The maximum value to render in the range axis. y-tick-font The font to render the range tick value in. y-tick-fmt-str The DecimalFormat string to render the numeric range tick value. enable-log-axis If set to true, displays the y-axis as a logarithmic scale. log-format If set to true, will present the logarithmic scale in a human readable view.
Read more
  • 0
  • 0
  • 5208

article-image-simple-item-selector-using-jquery
Packt
09 Nov 2009
4 min read
Save for later

Simple Item Selector Using jQuery

Packt
09 Nov 2009
4 min read
(For more resources on jQuery, see here.) Adding jQuery to your page You can download the latest version of jQuery from jQuery site (http://jquery.com/) and can be added as a reference to your web pages accordingly. You can reference a local copy of jQuery using <script> tag in the page. Either you can reference your local copy or you can directly reference remote copy from jQuery.com or Google Ajax API (http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js) Prerequisite Knowledge In order to understand the code, one should have the basic knowledge of HTML, CSS, JavaScript and basic knowledge of jQuery. Ingredients Used HTML CSS jQuery Photoshop (Used for Designing of Image Buttons and Backgrounds) Preview / Download If you would like to see the working example, please do click here http://www.developersnippets.com/snippets/jquery/item_selector/item_selector.html). And if you would like to download the snippet, click here (http://www.developersnippets.com/snippets/jquery/item_selector/item_selector.zip) Figure 1: Snapshot of "Simple Item Selector using jQuery" Figure 2: Overview of div containers and image buttons used Successfully tested The above application has been successfully tested on various browsers like IE 6.0, IE 7, IE 8, Mozilla Firefox (Latest Version), Google Chrome and Safari Browser (4.0.2) respectively. HTML Code Below is the HTML code with comments for you to understand it better. <!-- Container --><div id="container"> <!-- From Container --> <div class="from_container"> <select id="fromSelectBox" multiple="multiple"> <option value="1">Adobe</option> <option value="2">Oracle</option> <option value="3">Google</option> <option value="4">Microsoft</option> <option value="5">Google Talk</option> <option value="6">Google Wave</option> <option value="7">Microsoft Silver Light</option> <option value="8">Adobe Flex Professional</option> <option value="9">Oracle DataBase</option> <option value="10">Microsoft Bing</option> </select><br /> <input type="image" src="images/selectall.jpg" class="selectall" onclick="selectAll('fromSelectBox')" /><input type="image" src="images/deselectall.jpg" class="deselectall" onclick="clearAll('fromSelectBox')" /> </div> <!-- From Container [Close] --> <!-- Buttons Container --> <div class="buttons_container"> <input type="image" src="images/topmost.jpg" id="topmost" /><br /> <input type="image" src="images/moveup.jpg" id="moveup" /><br /> <input type="image" src="images/moveright.jpg" id="moveright" /><br /> <input type="image" src="images/moveleft.jpg" id="moveleft" /><br /> <input type="image" src="images/movedown.jpg" id="movedown" /><br /> <input type="image" src="images/bottommost.jpg" id="bottommost" /><br /> </div> <!-- Buttons Container [Close] --> <!-- To Container --> <div class="to_container"> <select id="toSelectBox" multiple="multiple"></select><br /> <input type="image" src="images/selectall.jpg" class="selectall" onclick="selectAll('toSelectBox')" /><input type="image" src="images/deselectall.jpg" class="deselectall" onclick="clearAll('toSelectBox')" /> </div> <!-- To Container [Close] --> <!-- To Container --> <div class="ascdes_container"> <input type="image" src="images/ascending.jpg" id="ascendingorder" style="margin:1px 0px 2px 0px;" onclick="ascOrderFunction()" /><br /> <input type="image" src="images/descending.jpg" id="descendingorder" onclick="desOrderFunction()" /> </div> <!-- To Container [Close] --> <div style="clear:both"></div></div><!-- Container [Close] -->
Read more
  • 0
  • 0
  • 2945

article-image-using-javascript-effects-joomla
Packt
06 Nov 2009
7 min read
Save for later

Using JavaScript Effects with Joomla!

Packt
06 Nov 2009
7 min read
Customizing Google Maps Google Maps has a comprehensive API for interacting with maps on your website. MooTools can be used to load the Google Maps engine at the correct time. It can also act as a bridge between the map and other HTML elements on your site. To get started, you will first need to get an API key to use Google Maps on your domain. You can sign up for a free key at http://code.google.com/apis/maps/signup.html. Even if you are working on your local computer, you still need the key. For instance, if the base URL of your Joomla installation is http://localhost/joomla, you will enter localhost as the domain for your API key. Once you have an API key ready, create the file basicmap.js in the /components/com_js folder, and fill it with the following code: window.addEvent('domready', function() { if (GBrowserIsCompatible()) { var map = new GMap2($('map_canvas')); map.setCenter(new GLatLng(38.89, -77.04), 12); window.onunload=function() { GUnload(); }; }}); The entire script is wrapped within a call to the MooTools-specific addEvent() member function of window. Because we want this code to execute once the DOM is ready, the first parameter is the event name 'domready'. The second parameter is an anonymous function containing our code. What does the call to function() do?Using function() in JavaScript is a way of creating an anonymous function. This way, you can create functions that are used in only one place (such as event handlers) without cluttering the namespace with a needless function name. Also, the code within the anonymous function operates within its own scope; this is referred to as a closure. Closures are very frequently used in modern JavaScript frameworks, for event handling and other distinct tasks. Once inside of the function, GBrowserIsCompatible() is used to determine if the browser is capable of running Google Maps. If it is, a new instance of GMap2() is declared and bound to the HTML element that has an id of 'map_canvas' and is stored into map. The call to $('map_canvas') is a MooTools shortcut for document.GetElementById(). Next, the setCenter() member function of map is called to tell Google Maps where to center the map and how far to zoom in. The first parameter is a GLatLng() object, which is used to set the specific latitude and longitude of the map's center. The other parameter determines the zoom level, which is set to 12 in this case. Finally, the window.onunload event is set to a function that calls GUnload(). When the user navigates away from the page, this function removes Google Maps from memory, to prevent memory leaks. With our JavaScript in place, it is now time to add a function to the controller in /components/com_js/js.php that will load it along with some HTML. Add the following basicMap() function to this file: function basicMap(){ $key = 'DoNotUseThisKeyGetOneFromCodeDotGoogleDotCom'; JHTML::_('behavior.mootools'); $document =& JFactory::getDocument(); $document->addScript('http://maps.google.com/maps?file=api&v= 2&key=' . $key); $document->addScript( JURI::base() . 'components/com_js/basicmap.js'); ?> <div id="map_canvas" style="width: 500px; height: 300px"></div> <?php} The basicMap() function starts off by setting $key to the API key received from Google. You should replace this value with the one you receive at http://code.google.com/apis/maps/signup.html. Next, JHTML::_('behavior.mootools'); is called to load MooTools into the <head> tag of the HTML document. This is followed by getting a reference to the current document object through the getDocument() member function of JFactory. The addScript() member function is called twice—once to load in the Google Maps API (using our key), then again to load our basicmap.js script. (The Google Maps API calls in all of the functions and class definitions beginning with a capital 'G'.) Finally, a <div> with an id of 'map_canvas' is sent to the browser. Once this function is in place and js.php has been saved, load index.php?option=com_js&task=basicMap in the browser. Your map should look like this: We can make this map slightly more interesting by adding a marker to a specific address. To do so, add the highlighted code below to the basicmap.js file: window.addEvent('domready', function() { if (GBrowserIsCompatible()) { var map = new GMap2($('map_canvas')); map.setCenter(new GLatLng(38.89, -77.04), 12); var whitehouse = new GClientGeocoder(); whitehouse.getLatLng('1600 Pennsylvania Ave NW', function(latlng) { marker = new GMarker( latlng ); marker.bindInfoWindowHtml('<strong>The White House</strong>'); map.addOverlay(marker); }); window.onunload=function(){ GUnload(); }; }}); This code sets whitehouse as an instance of the GClientGeocoder class. Next, the getLatLng() member function of GClientGeocoder is called. The first parameter is the street address to be looked up. The second parameter is an anonymous function where the GLatLng object is passed once the address lookup is complete. Within this function, marker is set as a new GMarker object, which takes the passed-in latlng object as a parameter. The bindInfoWindowHTML() member function of GMarker is called to add an HTML message to appear in a balloon above the marker. Finally, the maker is passed into the addOverlay() member function of GMap2, to place it on the map. Save basicmap.js and then reload index.php?option=com_js&task=basicMap. You should now see the same map, only with a red pin. When you click on the red pin, your map should look like this: Interactive Maps These two different maps show the basic functionality of getting Google Maps on your own website. These maps are very basic; you could easily create them at maps.google.com then embed them in a standard Joomla! article with the HTML code they provide you. However, you would not have the opportunity to add functions that interact with the other elements on your page. To do that, we will create some more HTML code and then write some MooTools-powered JavaScript to bridge our content with Google Maps. Open the /components/com_js/js.php file and add the following selectMap() function to the controller: function selectMap(){ $key = 'DoNotUseThisKeyGetOneFromCodeDotGoogleDotCom'; JHTML::_('behavior.mootools'); $document =& JFactory::getDocument(); $document->addScript('http://maps.google.com/maps?file=api&v =2&key=' . $key); $document->addScript( JURI::base() . 'components/com_js/selectmap.js'); ?> <div id="map_canvas" style="width: 500px; height: 300px"></div> <select id="map_selections"> <option value="">(select...)</option> <option value="1200 K Street NW">Salad Surprises</option> <option value="1221 Connecticut Avenue NW">The Daily Dish</option> <option value="701 H Street NW">Sushi and Sashimi</option> </select><?php} This function is almost identical to basicMap() except for two things—selectmap.js is being added instead of basicmap.js, and a <select> element has been added beneath the <div>. The <select> element has an id that will be used in the JavaScript. The options of the <select> element are restaurants, with different addresses as values. The JavaScript code will bind a function to the onChange event so that the marker will move as different restaurants are selected.
Read more
  • 0
  • 0
  • 5030

article-image-including-charts-and-graphics-pentaho-reports-part-2
Packt
29 Oct 2009
6 min read
Save for later

Including Charts and Graphics in Pentaho Reports (Part 2)

Packt
29 Oct 2009
6 min read
Ring chart The ring chart is identical to the pie chart, except that it renders as a ring versus a complete pie. In addition to sharing all the properties similar to the pie chart, it also defines the following rendering property : Options Property Group Property name Description section-depth This property defines the percentage of the radius to render the section as. The default value is set to 0.5. Ring chart example For this example, simply open the defined pie chart example and select the Ring chart type. Also, set the section-depth to 0.1, in order to generate the following effect: Multi pie chart The multi pie chart renders a group of pie charts, based on a category dataset. This meta-chart renders individual series data as a pie chart, each broken into individual categories within the individual pie charts. The multi pie chart utilizes the common properties defined above, including the category dataset properties. In addition to the standard set of properties, it also defines the following two properties: Options Property Group Property name Description label-format This label defines how each item within a chart is rendered. The default value is set to "{0}". The format string may also contain any of the following: {0}: To render the item name {1}: To render the item value {2}: To render the item percentage in relation to the entire pie chart by-row This value defaults to True. If set to False, the series and category fields are reversed, and individual charts render series information. Note that the horizontal, series-color, stacked and stacked-percent properties do not apply to this chart type. Multi pie chart example This example demonstrates the distribution of purchased item types, based on payment type. To begin, create a new report. You'll reuse the bar chart's SQL query. Now, place a new Chart element into the Report Header. Edit the chart, selecting Multi Pie as the chart type. To configure the dataset for this chart, select ITEMCATEGORY as the category-column. Set the value-columns property to QUANTITY and the series-by-field to PAYMENTTYPE. Waterfall chart The waterfall chart displays a unique stacked bar chart that spans categories. This chart is useful when comparing categories to one another. The last category in a waterfall chart normally equals the total of all the other categories to render appropriately, but this is based on the dataset, not the chart rendering. The waterfall chart utilizes the common properties defined above, including the category dataset properties. The stacked property is not available for this chart. There are no additional properties defined for the waterfall chart. Waterfall chart example In this example, you'll compare by type, the quantity of items in your inventory. Normally, the last category would be used to display the total values. The chart will render the data provided with or without a summary series, so you'll just use the example SQL query from the bar chart example. Add a Chart element to the Report Header and select Waterfall as the chart type. Set the category-column to ITEMCATEGORY, the value-columns to QUANTITY, and the series-by-value property to Quantity. Now, apply your changes and preview the results. Bar line chart The bar line chart combines the bar and line charts, allowing visualization of trends with categories, along with comparisons. The bar line chart is unique in that it requires two category datasets to populate the chart. The first dataset populates the bar chart, and the second dataset populates the line chart. The bar line chart utilizes the common properties defined above, including the category dataset properties. This chart also inherits the properties from both the bar chart, as well as the line chart. This chart also has certain additional properties, which are listed in the following table: Required Property Group Property name Description bar-data-source The name of the first dataset required by the bar line chart, which populates the bars in the chart. This value is automatically populated with the correct name. line-data-source The name of the second dataset required by the bar line chart, which populates the lines in the chart. This value is automatically populated with the correct name. Bar Options Property Group Property name Description ctgry-tick-font Defines the Java font that renders the Categories. Line Options Property Group Property name Description line-series-color Defines the color in which to render each line series. line-tick-fmt Specifies the Java DecimalFormat string for rendering the Line Axis Labels lines-label-font Defines the Java font to use when rendering line labels. line-tick-font Defines the Java font to use when rendering the Line Axis Labels. As part of the bar line chart, a second y-axis is defined for the lines. The property group Y2-Axis is available with similar properties as the standard y-axis. Bar line chart example To demonstrate the bar line chart, you'll reuse the SQL query from the area chart example. Create a new report, and add a Chart element to the Report Header. Edit the chart, and select Bar Line as the chart type. You'll begin by configuring the first dataset. Set the category-column to ITEMCATEGORY, the value-columns to COST, and the series-by-value property to Cost. To configure the second dataset, set the category-column to ITEMCATEGORY, the value-columns to SALEPRICE, and the series-by-value property to Sale Price. Set the x-axis-label-width to 2.0, and reduce the x-font size to 7. Also, set show-legend to True. You're now ready to preview the bar line chart. Bubble chart The bubble chart allows you to view three dimensions of data. The first two dimensions are your traditional X and Y dimensions, also known as domain and range. The third dimension is expressed by the size of the individual bubbles rendered. The bubble chart utilizes the common properties defined above, including the XY series dataset properties. The bubble chart also defines the following properties: Options Property Group Property name Description max-bubble-size This value defines the diameter of the largest bubble to render. All other bubble sizes are relative to the maximum bubble size. The default value is 0, so this value must be set to a reasonable value for rendering of bubbles to take place. Note that this value is based on pixels, not the domain or range values. The bubble chart defines the following additional dataset property: Required Property Group Property name Description z-value-columns This is the data source column to use for Z value, which specifies the bubble diameter relative to the maximum bubble size. Bubble chart example In this example, you need to define a three dimensional SQL query to populate the chart. You'll use inventory information, and calculate Item Category Margin: SELECT"INVENTORY"."ITEMCATEGORY","INVENTORY"."ONHAND","INVENTORY"."ONORDER","INVENTORY"."COST","INVENTORY"."SALEPRICE","INVENTORY"."SALEPRICE" - "INVENTORY"."COST" MARGINFROM"INVENTORY"ORDER BY"INVENTORY"."ITEMCATEGORY" ASC Now that you have a SQL query to work with, add a Chart element to the Report Header and select Bubble as the chart type. First, you'll populate the correct dataset fields. Set the series-by-field property to ITEMCATEGORY. Now, set the X, Y, and Z value columns to ONHAND, SALEPRICE, and MARGIN. You're now ready to customize the chart rendering. Set the x-title to On Hand, the y-title to Sales Price, the max-bubble-size to 100, and the show-legend property to True. The final result should look like this:
Read more
  • 0
  • 0
  • 4011

article-image-managing-manufacturers-vendors-and-product-categories-joomla-e-commerce-virtuemart
Packt
28 Oct 2009
7 min read
Save for later

Managing Manufacturers, Vendors, and Product Categories with Joomla! E-Commerce VirtueMart

Packt
28 Oct 2009
7 min read
We are going to add and edit a lot of information for manufacturers, vendors, and product categories. Actually, in this article, our VirtueMart shop will really take shape with products we want to sell. Catalogue management The product catalog for an online shop comprises of the products we sell in the shop. Whatever products we want to sell should be added to this product catalog first. Once products are added to the catalog, customers can browse the products and decide to buy whatever they need. Therefore, managing the catalog is one of the primary tasks of the shop owner. Products that we add to the catalog need to be organized to help customers easily find the right products. In VirtueMart, customers can sort the products by product categories and manufacturers. Therefore, before adding products to the catalog, we will look into managing manufacturers and product categories. Managing manufacturers In VirtueMart, whenever we add a product to the catalog, we also need to assign a manufacturer for that product. In reality, every product has a manufacturer, and for better management of the shop, we should be able to find products by their manufacturer. Therefore, first step will be to identify the manufacturers and enter their information in VirtueMart store. We can also categorize the manufactures as publishers, software developers, and so on. Adding a manufacturer category There is a default manufacturer category for use in VirtueMart. We can use that default category for creating a manufacturer. However, when we are selling large number of products from a large number of manufacturers, classifying them into categories will be convenient for managing the manufacturers. For adding a manufacturer, in the VirtueMart administration panel, click on Manufacturer | Add Manufacturer Category. This shows Manufacturer Category Form: In the Manufacturer Category Form, provide information for the Category Name and the Category Description fields. Once these are provided, click the Save icon in the toolbar to save the manufacturer category. In the same process, you can add as many categories as you want. Adding a manufacturer For adding a manufacturer, in the VirtueMart administration panel, select Manufacturer | Add Manufacturer. This shows Add Information screen: In the Add Information screen, type the manufacturer's name, their URL, email address, and a brief description. In the Manufacturer Category field, select the category. The drop-down list will show the manufacturer categories you created earlier. Once all the information is provided in this screen, click the Save icon in the toolbar to save the manufacturer information. Listing the manufacturer categories Once you have added the manufacturer categories, you can view the list of manufacturer categories by selecting Manufacturer | List Manufacturer Categories. This shows Manufacturer Category List screen: In the Manufacturer Category List screen, you will see all manufacturer categories you have created. From this screen, you can add a new category by clicking the New icon in the toolbar. Similarly, you can remove a category by clicking on the trash icon in Remove column, or by selecting the categories and clicking the Remove icon in the toolbar. You can edit a category by clicking on the category name. To view the list of manufacturers, click on the Manufacturer List link in the Manufacturers column, or select Manufacturer | List Manufacturers. This shows Manufacturer List screen displaying all manufacturers you have added: From the Manufacturer List screen, you can create a new manufacturer, remove one or more manufacturers, and edit any manufacturer. For editing a manufacturer, click on the manufacturer's name or the Update link in Admin column. This will bring up the Add Information screen again. You can also create a new manufacturer by clicking the New icon in the toolbar. From the Manufacturer Category List screen, you may think that clicking on the Manufacturer List link against each category will display the manufacturers added to that category only. Ideally, this should be the case. However, until VirtueMart 1.1.2, it shows the list of manufacturers from all the categories. We hope this will be fixed in the upcoming releases of VirtueMart. Managing vendors The idea of multiple vendors is something what you can see on Amazon.com. Different vendors add their products to sell, when the order is placed, the store notifies the vendor to fulfill the order. The main store usually gets a commission from the vendor for each sell made through the store. However, VirtueMart's vendors feature is still in its infancy and does not yet function properly. You can add multiple vendors in VirtueMart, and assign products to the vendors. However, adding vendors has no effect on selling any product on the VirtueMart store, except when applying different vendor-specific tax rates and shopper groups. At the moment, it also helps to identify products from different vendors. In the following sections, you will see how to add and manage vendors. Vendor category Like manufacturers, you can also create vendor categories. For creating vendor categories, go to Vendor | Add Vendor Category. This displays Vendor Category Form: In the Vendor Category Form, type the name of the category and its description. Then click the Save icon in the toolbar. You can add as many categories as you want. Before trying to add vendor categories, first plan how you are going to categorize your vendors (for example, based on the product they sell or their location). Have a full category tree on hand and then start creating categories. Adding vendor Once you have created the necessary vendor categories, you can proceed to adding vendors. For adding vendors, click on Vendor | Add Vendor. This displays the Add Information screen: CautionNote that there is a warning sign at the top of Add Information screen. It warns you about using the vendor feature as it is in the 'Alpha' or pre-mature stage. Also note that we have used Simple Layout for displaying it. If you try adding a vendor from Extended Layout, you will open up an edit screen for existing vendor information, which you already added during the initial configuration of the shop. Up until VirtueMart 1.1.2, a bug has been encountered and which will hopefully be fixed in future releases when it crosses 'Alpha' stage. The Add Information screen shows three tabs: Store, Store Information, and Contact Information. From the Store tab, add the vendor's store name, company name, logo, web site URL, minimum purchase order value, and minimum amount for free shipping. You can also configure the currency symbol, decimal points, decimal symbol, thousand separator, positive format, and negative format. In the Store Information tab (seen in the previous screenshot), you can add the address of the store, city, state/province/region, zip/postal code, phone, currency and vendor category. The vendor categories you have created earlier will be available in Vendor Category drop-down list. In the Contact Information tab (seen in the previous screenshot), you can set the contact details of the vendor, such as name, title, phone, fax, email. You can also add a brief description of the vendor which will be displayed in the vendor details page in the store. Type a brief description in the Description rich-text editing box. In the Terms of Service rich-text editing box, provide terms of service applicable for that vendor. Once information in all the three tabs are provided, click the Save icon in the toolbar to add the vendor.
Read more
  • 0
  • 0
  • 4367
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-external-tables-oracle-10g11g-database-part-2
Packt
28 Oct 2009
13 min read
Save for later

External Tables in Oracle 10g/11g Database: Part 2

Packt
28 Oct 2009
13 min read
Data transformation with External Tables One of the main uses of the External Tables is their support of the ETL process, allowing the user to perform a data load that is transformed to the target format without an intermediate stage table. Let's read an External Table whose contents are: This data can be loaded in a single command to multiple tables. Let's create several tables with the same structure: SQL> desc amount_jan Name Null? Type ----------------- -------- ------------ REGION VARCHAR2(16) AMOUNT NUMBER(3) Now issue the command to send the data from the external table to the different tables. INSERT ALL INTO AMOUNT_JAN (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_FEB (REGION, AMOUNT) VALUES(COUNTRY, FEB) INTO AMOUNT_MAR (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_APR (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_MAY (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_JUN (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_JUL (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_AUG (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_SEP (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_OCT (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_NOV (REGION, AMOUNT) VALUES(COUNTRY, JAN) INTO AMOUNT_DEC (REGION, AMOUNT) VALUES(COUNTRY, JAN)SELECT COUNTRY, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DECFROM REGION_REVENUE; In this example, we will perform a conditional insert to different tables depending on the value of the amount column. We will first create three tables, one for low, another for average, and a third for high amounts: SQL> create table low_amount( 2 region varchar2(16), 3 month number(2), 4 amount number(3));Table created.SQL> create table high_amount as select * from low_amount;Table created. Now we can read the External Table and have the data inserted conditionally to one of three mutually exclusive targets. INSERT ALL WHEN ( JAN <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '01', JAN ) WHEN ( FEB <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '02', FEB ) WHEN ( MAR <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '03', MAR ) WHEN ( APR <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '04', APR ) WHEN ( MAY <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '05', MAY ) WHEN ( JUN <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '06', JUN ) WHEN ( JUL <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '07', JUL ) WHEN ( AUG <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '08', AUG ) WHEN ( SEP <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '09', SEP ) WHEN ( OCT <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '10', OCT ) WHEN ( NOV <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '11', NOV ) WHEN ( DEC <= 500 ) THEN INTO LOW_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '12', DEC ) WHEN ( JAN > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '01', JAN ) WHEN ( FEB > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '02', FEB ) WHEN ( MAR > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '03', MAR ) WHEN ( APR > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '04', APR ) WHEN ( MAY > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '05', MAY ) WHEN ( JUN > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '06', JUN ) WHEN ( JUL > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '07', JUL ) WHEN ( AUG > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '08', AUG ) WHEN ( SEP > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '09', SEP ) WHEN ( OCT > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '10', OCT ) WHEN ( NOV > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '11', NOV ) WHEN ( DEC > 500 ) THEN INTO HIGH_AMOUNT( REGION, MONTH, AMOUNT) VALUES ( COUNTRY, '12', DEC )SELECT COUNTRY, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DECFROM REGION_REVENUE; Extending the alert.log analysis with External Tables Reading the alert.log from the database is a useful feature which can help you to find any outstanding error messages reported in this file. create table ALERT_LOG ( text_line varchar2(512)) organization external ( type ORACLE_LOADER default directory BACKGROUND_DUMP_DEST access parameters( records delimited by newline nobadfile nodiscardfile nologfile ) location( 'alert_beta.log') ); Once the External Table has been created, the alert.log file can be queried just like any other regular table. SQL> select text_line from alert_log 2 where text_line like 'ORA-%';TEXT_LINE-----------------------------------------------------------------ORA-1109 signalled during: ALTER DATABASE CLOSE NORMAL...ORA-00313: open failed for members of log group 1 of thread 1ORA-00312: online log 1 thread 1: '/u01/oracle/oradata/beta/redo01.log'ORA-27037: unable to obtain file statusORA-00313: open failed for members of log group 2 of thread 1ORA-00312: online log 2 thread 1: '/u01/oracle/oradata/beta/redo02.log'ORA-27037: unable to obtain file statusORA-00313: open failed for members of log group 3 of thread 1ORA-00312: online log 3 thread 1: '/u01/oracle/oradata/beta/redo03.log'ORA-27037: unable to obtain file status Querying the alert.log file up to this phase is useful just to see the contents of the file and look for basic ORA-% strings. This could also be achieved by using the alert.log link in the Enterprise Manager (EM). The alert.log file can be queried by means of the EM, but as this can only be viewed from the EM in an interactive mode, you can only rely on the preset alerts. If further automatic work needs to be done, then it is useful to do some more work with the alert analysis tool. A temporary table can be used to store the contents of the ALERT_LOG table, along with an extra TIMESTAMP column, so it can be queried in detail in an EM-like manner. create global temporary table TMP_ALERT_LOG ( LINE_NO NUMBER(6), TIMESTAMP DATE, TEXT_LINE VARCHAR2(512))on commit preserve rows; A bit of PLSQL programming is necessary so the ALERT_LOG file can be modified and inserted into the TMP_ALERT_LOG, (enabling further queries can be done). declarecursor alertLogCur is select ROWNUM, TEXT_LINE from ALERT_LOG;currentDate date;altertLogRec ALERT_LOG.TEXT_LINE%TYPE;testDay varchar2(10);begincurrentDate := sysdate;for alertLogInst in alertLogCur loop -- fetch row and determine if this is a date row testDay := substr(alertLogInst.text_line, 1, 3); if testDay = 'Sun' or testDay = 'Mon' or testDay = 'Tue' or testDay = 'Wed' or testDay = 'Thu' or testDay = 'Fri' or testDay = 'Sat' then -- if this is a date row, it sets the current logical record date currentDate := to_date( alertlogInst.text_line, 'Dy Mon DD HH24:MI:SS YYYY'); end if; insert into TMP_ALERT_LOG values( alertLogInst.rownum, currentDate, alertLogInst.text_line );end loop;end;/ As the contents of the alert.log end up in a temporary table, more than one DBA can query it at the same time, or restrict the DBA's accessibilities. There is no need to manage the purge and maintenance of the table after the session has ended, it can be indexed and there is little overhead by means of this procedure. Moreover, as this is a temporary object, minimum redo log information is generated. Once the external ALERT_LOG and the temporary ALERT_LOG tables have been created, it is possible to perform, not only filters by date (provided by Enterprise Manager) but also any query against the alert.log file. SELECT TIMESTAMP, TEXT_LINEFROM TMP_ALERT_LOGWHERE TIMESTAMP IN ( SELECT TIMESTAMP FROM TMP_ALERT_LOG WHERE TEXT_LINE LIKE 'ORA-%')AND TIMESTAMP BETWEEN SYSDATE-30 AND SYSDATEORDER BY LINE_NO; Further treatment can be done on this concept to look for specific error messages, analyze specific time frames and perform drill down analysis. This procedure can be extended to read the trace files or any other text file from the database. Reading the listener.log from the database One particular extension of the above procedure is to read the listener.log file. This file has a specific star-delimited field file format which can be advantageous, and eases the read by means of the Loader driver. The file format is as follows: 21-JUL-2008 00:39:50 * (CONNECT_DATA=(SID=beta)(CID=(PROGRAM=perl)(HOST=alpha.us.oracle.com)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.2.10)(PORT=8392)) * establish * beta * 021-JUL-2008 00:39:56 * (CONNECT_DATA=(SID=beta)(CID=(PROGRAM=perl)(HOST=alpha.us.oracle.com)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.2.10)(PORT=8398)) * establish * beta * 021-JUL-2008 00:40:16 * service_update * beta * 021-JUL-2008 00:41:19 * service_update * beta * 021-JUL-2008 00:44:43 * ping * 0 The file has a format that can be deduced from the above data sample: TIMESTAMP * CONNECT DATA [* PROTOCOL INFO] * EVENT [* SID] * RETURN CODE As you can see this format, even though it is structured, it may have a different number of fields, so at loading time this issue must be considered. In order for us to map this table to the database, we should consider the variable number of fields to have the External Table created. We'll create a temporary table so that this doesn't create an additional transactional overhead. Now, let's create an External Table based on this format that points to $ORACLE_HOME/network/log: create directory NETWORK_LOG_DIRas '$ORACLE_HOME/network/log'; Now, let's create the external table: create table LISTENER_LOG ( TIMESTAMP date, CONNECT_DATA varchar2(2048), PROTOCOL_INFO varchar2(64), EVENT varchar2(64), SID varchar2(64), RETURN_CODE number(5))organization external ( type ORACLE_LOADER default directory NETWORK_LOG_DIR access parameters ( records delimited by NEWLINE nobadfile nodiscardfile nologfile fields terminated by "*" LDRTRIM reject rows with all null fields ( "TIMESTAMP" char date_format DATE mask "DD-MON-YYYY HH24:MI:SS ", "CONNECT_DATA", "PROTOCOL_INFO", "EVENT", "SID", "RETURN_CODE" ) ) location ('listener.log'))reject limit unlimited; The structure of interest is specified above, so there will be several rows rejected. Seeing as this file is not fully structured, you will find some non formatted information; the bad file and the log file are not meaningful in this context. Another application of the LISTENER_LOG External Table is usage trend analysis. This query can be issued to detect usage peak hours. SQL> select to_char(round(TIMESTAMP, 'HH'), 'HH24:MI') HOUR, 2 lpad('#', count(*), '#') CX 3 from listener_log 4 group by round(TIMESTAMP, 'HH') 5 order by 1;HOUR CX----- ------------------------------------------------14:00 ###15:00 ##########################16:00 ######################17:00 #####################18:00 #####################19:00 ############### Reading the listener.log file this way allows the DBA not only to keep track of the listener behavior, but also it allows a security administrator to easily spot hacking attempts. Let's find out who is trying to access the database with sqlplus.exe. SQL> select timestamp, protocol_info 2 from listener_log 3 where connect_data like '%sqlplus.exe%' 4 /TIMESTAMP PROTOCOL_INFO-------------------- --------------------------------------------------------01-SEP-2008 14:30:37 (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.2.101)(PORT=3651))01-SEP-2008 14:31:08 (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.2.101)(PORT=3666))01-SEP-2008 14:31:35 (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.2.101)(PORT=3681)) The use of External Tables to analyze the listener.log can be used not only to have an in-database version of the listener.log perform periodic and programmatic analysis of the listener behavior, but also to determine usage trends and correlate information with the audit team so that unauthorized connection programs can be easily and quickly spotted. Further useful applications can be found by reading the listener.log file. There are two fields that must be further parsed to get information out of them, but parsing those fields goes beyond the scope of this article. The structure that the analysis should consider is detailed next: Connect String SID: The Database Oracle SID, which is populated if the connection was performed by SID, otherwise it is NULL. CID: It contains two subfields, PROGRAM and HOST. SERVER: This field indicates the connection type, either dedicated or shared. SERVICE_NAME: This field is populated when the connection is performed by a Service instead of SID. COMMAND: The command issued by the user. SERVICE: Present only when listener commands are issued. FAILOVER_MODE: In Real Application Clusters (RAC) environments this field is used if the client performed a connection due to a failover. It shows the failover mode used. Protocol PROTOCOL: Indicates the used to perform the connection; this will be TCP most of the times. HOST: This is the client's IP Address. PORT: The port number of the oracle server used to establish the connection. Mapping XML files as External Tables XML has become a de facto information exchange format, which is why oracle has included the XML Database (XDB) feature from 9.2.0. However, it requires the data to be actually loaded into the database before it can be processed. An External Table allows the user to take a quick look at the contents of the external file prior to performing any further processing. In this example an External Table is created out of an XML file. This file is read by means of a CLOB field, and some further XDB commands can be issued against the external XML file to extract and view data. Let's create the external XML file first: create table EMPLOYEES_XML (xmlFile CLOB)organization external ( type ORACLE_LOADER default directory EXTTABDIR access parameters ( fields (xmllob char terminated by ',') column transforms (xmlFile from lobfile(xmllob)) ) location('employees.dat'))reject limit unlimited; The employees.dat file contains the file name of the XML file to load as an external CLOB file. This file, for the purpose of the demo, contains the file name: employees.xml. Now the file can be queried from the database as if it was a regular table with a single XML column. Dynamically changing the external reference When managing External Tables, there should be an easy way to redefine the external source file. It is enough to change the External Table properties by means of an ALTER TABLE command. Let's create a stored procedure that performs this task by means of a dynamically generated DDL command. This procedure, named Change_External_Table redefines the location property. Using a stored program unit is a flexible way to perform this task. create procedure change_external_table( p_table_name in varchar2, p_file_name in varchar2) isbeginexecute immediate 'alter table '|| p_table_name|| ' location ('''|| p_file_name|| ''')' ;exceptionwhen othersthenraise_application_error(sqlcode,sqlerrm) ;end ;/ Oracle 11g External Table enhancements External Tables work the same in 10g and in 11g, so there are no differences when working with these two versions. When working with Data Pump External Tables, and one single row proves defective, the data set reading operation is aborted. An enhancement in this 11g release prevents the data load aborting, thus saving reprocessing time. Summary Managing data with External Tables is a means not only for mapping external flat files as regular (but limited) tables inside the database, but also a tool to more efficiently perform administrative tasks such as programmatically processing database log files such as the alert.log or the listener.log files. It can be used to easily view external XML formatted files from inside the database without actually loading the file to the database. It can also be used as a means of unloading data in temporary external storage to exchange data among different Oracle versions. This particular feature allows the user to easily build an Oracle Datamart that allows the pre-formatting and summarization of data from the source, enabling it to be directly inserted into the target data warehouse.
Read more
  • 0
  • 0
  • 2900

article-image-using-business-rules-define-decision-points-oracle-soa-suite-part-1
Packt
28 Oct 2009
11 min read
Save for later

Using Business Rules to Define Decision Points in Oracle SOA Suite: Part 1

Packt
28 Oct 2009
11 min read
The advantage of separating out decision points as external rules is that we not only ensure that each rule is used in a consistent fashion, but in addition make it simpler and quicker to modify; that is we only have to modify a rule once and can do this with almost immediate effect, thus increasing the agility of our solution. Business Rule concepts Before we implement our first rule, let's briefly introduce the key components which make up a Business Rule. These are: Facts: Represent the data or business objects that rules are applied to. Rules: A rule consists of two parts, an IF part which consists of one or more tests to be applied to fact(s), and a THEN part, which lists the actions to be carried out should the test to evaluate to true Rule Set: As the name implies, it is just a set of one or more related rules that are designed to work together . Dictionary: A dictionary is the container of all components that make up a business rule, it holds all the facts, rule sets, and rules for a business rule. In addition, a dictionary may also contain functions, variables, and constraints. We will introduce these in more detail later in this article. To execute a business rule, you submit one or more facts to the rules engine. It will apply the rules to the facts, that is each fact will be tested against the IF part of the rule and if it evaluates to true, then it will perform the specified actions for that fact. This may result in the creation of new facts or the modification of existing facts (which may result in further rule evaluation). Leave approval rule To begin with, we will write a simple rule to automatically approve a leave request that is of type Vacation and only for 1 day's duration. A pretty trivial example, but once we've done this we will look at how to extend this rule to handle more complex examples. Using the Rule Author In SOA Suite 10.1.3 you use the Rule Author, which is a browser based interface for defining your business rules. To launch the Rule Author within your browser go to the following URL: http://<host name>:<port number>/ruleauthor/ This will bring up the Rule Author Log In screen. Here you need to log in as user that belongs to the rule-administrators role. You can either log in as the user oc4jadmin (default password Welcome1), which automatically belongs to this group, or define your own user. Creating a Rule Repository Within Oracle Business Rules, all of our definitions (that is facts, constraints, variables, and functions) and rule sets are defined within a dictionary. A dictionary is held within a Repository. A repository can contain multiple dictionaries and can also contain multiple versions of a dictionary. So, before we can write any rules, we need to either connect to an existing repository, or create a new one. Oracle Business Rules supports two types of repository—File based and WebDAV. For simplicity we will use a File based repository, though typically in production you want to use a WebDAV based repository as this makes it simpler to share rules between multiple BPEL Processes. WebDAV is short for Web-based Distributed Authoring and Versioning. It is an extension to HTTP that allows users to collaboratively edit and manage files (that is business rules in our case) over the Web. To create a File based repository click on the Repository tab within the Rule Author, this will display the Repository Connect screen as shown in the following screenshot: From here we can either connect to an existing repository (WebDAV or File based) or create and connect to a new file-based repository. For our purposes, select a Repository Type of File, and specify the full path name of where you want to create the repository and then click Create. To use a WebDAV repository, you will first need to create this externally from the Rule Author. Details on how to do this can be found in Appendix B of the Oracle Business Rules User Guide (http://download.oracle.com/docs/cd/B25221_04/web.1013/b15986/toc.htm). From a development perspective it can often be more convenient to develop your initial business rules in a file repository. Once complete, you can then export the rules from the file repository and import them into a WebDAV repository. Creating a dictionary Once we have connected to a repository, the next step is to create a dictionary. Click on the Create tab, circled in the following screenshot, and this will bring up the Create Dictionary screen. Enter a New Dictionary Name (for example LeaveApproval) and click Create. This will create and load the dictionary so it's ready to use. Once you have created a dictionary, then next time you connect to the repository you will select the Load tab (next to the Create tab) to load it. Defining facts Before we can define any rules, we first need to define the facts that the rules will be applied to. Click on the Definitions tab, this will bring up the page which summarizes all the facts defined within the current dictionary. You will see from this that the rule engine supports three types of facts: Java Facts, XML Facts, and RL Facts. The type of fact that you want to use really depends on the context in which you will be using the rules engine. For example, if you are calling the rule engine from Java, then you would work with Java Facts as this provides a more integrated way of combining the two components. As we are using the rule engine with BPEL then it makes sense to use XML Facts. Creating XML Facts The Rule Author uses XML Schemas to generate JAXB 1.0 classes, which are then imported to generate the corresponding XML Facts. For our example we will use the Leave Request schema, shown as follows for convenience: <?xml version="1.0" encoding="windows-1252"?> <xsd:schema targetNamespace="http://schemas.packtpub.com/LeaveRequest" elementFormDefault="qualified" > <xsd:element name="leaveRequest" type="tLeaveRequest"/> <xsd:complexType name="tLeaveRequest"> <xsd:sequence> <xsd:element name="employeeId" type="xsd:string"/> <xsd:element name="fullName" type="xsd:string" /> <xsd:element name="startDate" type="xsd:date" /> <xsd:element name="endDate" type="xsd:date" /> <xsd:element name="leaveType" type="xsd:string" /> <xsd:element name="leaveReason" type="xsd:string"/> <xsd:element name="requestStatus" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema> Using JAXB, particularly when used in conjunction with BPEL, places a number of constraints on how we define our XML Schemas, including: When defining rules, the Rule Author can only work with globally defined types. This is because it's unable to introspect the properties (i.e. attributes and elements) of global elements. Within BPEL you can only define variables based on globally defined elements. The net result is that any facts we want to pass from BPEL to the rules engine (or vice versa) must be defined as global elements for BPEL and have a corresponding global type definition so that we can define rules against it. The simplest way to achieve this is to define a global type (for example tLeaveRequest in the above schema) and then define a corresponding global element based on that type (for example, leaveRequest in the above schema). Even though it is perfectly acceptable with XML Schemas to use the same name for both elements and types, it presents problems for JAXB, hence the approach taken above where we have prefixed every type definition with t as in tLeaveRequest. Fortunately this approach corresponds to best practice for XML Schema design. The final point you need to be aware of is that when creating XML facts the JAXB processor maps the type xsd:decimal to java.lang.BigDecimal and xsd:integer to java.lang.BigInteger. This means you can't use the standard operators (for example >, >=, <=, and <) within your rules to compare properties of these types. To simplify your rules, within your XML Schemas use xsd:double in place of xsd:decimal and xsd:int in place of xsd:integer. To generate XML facts, from the XML Fact Summary screen (shown previously), click Create, this will display the XML Schema Selector page as shown: Here we need to specify the location of the XML Schema, this can either be an absolute path to an xsd file containing the schema or can be a URL. Next we need to specify a temporary JAXB Class Directory in which the generated JAXB classes are to be created. Finally, for the Target Package Name we can optionally specify a unique name that will be used as the Java package name for the generated classes. If we leave this blank, the package name will be automatically generated based on the target namespace of the XML Schema using the JAXB XML-to-Java mapping rules. For example, our leave request schema has a target namespace of http://schemas.packtpub.com/LeaveRequest; this will result in a package name of com.packtpub.schemas.leaverequest. Next click on Add Schema; this will cause the Rule Author to generate the JAXB classes for our schema in the specified directory. This will update the XML Fact Summary screen to show details of the generated classes; expand the class navigation tree until you can see the list of all the generated classes, as shown in the following screenshot: Select the top level node (that is com) to specify that we want to import all the generated classes. We need to import the TLeaveRequest class as this is the one we will use to implement rules and the LeaveRequest class as we need this to pass this in as a fact from BPEL to the rules engine. The ObjectFactory class is optional, but we will need this if we need to generate new LeaveRequest facts within our rule sets. Although we don't need to do this at the moment it makes sense to import it now in case we do need it in the future. Once we have selected the classes to be imported, click Import (circled in previous screenshot) to load them into the dictionary. The Rule Author will display a message to confirm that the classes have been successfully imported. If you check the list of generated JAXB classes, you will see that the imported classes are shown in bold. In the process of importing your facts, the Rule Author will assign default aliases to each fact and a default alias to all properties that make up a fact, where a property corresponds to either an element or an attribute in the XML Schema. Using aliases Oracle Business Rules allows you to specify your own aliases for facts and properties in order to define more business friendly names which can then be used when writing rules. For XML facts if you have followed standard naming conventions when defining your XML Schemas, we typically find that the default aliases are clear enough and that if you start defining aliases it can actually cause more confusion unless applied consistently across all facts. Hiding facts and properties The Rule Author lets you hide facts and properties so that they don't appear in the drop downs within the Rule Author. For facts which have a large number of properties, hiding some of these can be worth while as it can simplify the creation of rules. Another obvious use of this might be to hide all the facts based on elements, since we won't be implementing any rules directly against these. However, any facts you hide will also be hidden from BPEL, so you won't be able to pass facts of these types from BPEL to the rules engine (or vice versa). In reality, the only fact you will typically want to hide will be the ObjectFactory (as you will have one of these per XML Schema that you import). Saving the rule dictionary As you define your business rules, it makes sense to save your work at regular intervals. To save the dictionary, click on the Save Dictionary link in the top right hand corner of the Rule Author page. This will bring up the Save Dictionary page. Here either click on the Save button to update the current version of the dictionary with your changes or, if you want to save the dictionary as a new version or under a new dictionary name, then click on the Save As link and amend the dictionary name and version as appropriate.
Read more
  • 0
  • 0
  • 2268

article-image-using-spring-faces
Packt
28 Oct 2009
13 min read
Save for later

Using Spring Faces

Packt
28 Oct 2009
13 min read
Using Spring Faces Module The following section shows you how to use the Spring Faces module. Overview of all tags of the Spring Faces tag library The Spring Faces module comes with a set of components, which are provided through a tag library. If you want more detailed information about the tag library, look at the following files inside the Spring Faces source distribution: spring-faces/src/main/resources/META-INF/spring-faces.tld spring-faces/src/main/resources/META-INF/springfaces.taglib.xml spring-faces/src/main/resources/META-INF/faces-config.xml If you want to see the source code of a specific tag, refer to faces-config.xml and springfaces.taglib.xml to get the name of the class of the component. The spring-faces.tld file can be used for documentation issues. The following table should give you a short description about the available tags from the Spring Faces component library: Name of the tag Description includeStyles The includeStyles tag renders the necessary CSS stylesheets which are essential for the components from Spring Faces. The usage of this tag in the head section is recommended for performance optimization. If the tag isn't included, the necessary stylesheets are rendered on the first usage of the tag. If you are using a template for your pages, it's a good pattern to include the tag in the header of that template. For more information about performance optimization, refer to the Yahoo performance guidelines, which are available at the following URL: http://developer.yahoo.com/performance. Some tags (includeStyles, resource, and resourceGroup) of the Spring Faces tag library are implementing patterns to optimize the performance on client side. resource The resource tag loads and renders a resource with ResourceServlet. You should prefer this tag instead of directly including a CSS stylesheet or a JavaScript file because ResourceServlet sets the proper response headers for caching the resource file. resourceGroup With the resourceGroup tag, it is possible to combine all resources which are inside the tag. It is important that all resources are the same type. The tag uses ResourceServlet with the appended parameter to create one resource file which is sent to the client. clientTextValidator With the clientTextValidator tag, you can validate a child inputText element. For the validation, you have an attribute called regExp where you can provide a regular expression. The validation is done on client side. clientNumberValidator With the clientNumberValidator tag, you can validate a child inputText element. With the provided validation methods, you can check whether the text is a number and check some properties for the number, e.g. range. The validation is done on client side. clientCurrencyValidator With the clientCurrencyValidator tag, you can validate a child inputText element. This tag should be used if you want to validate a currency. The validation is done on client side. clientDateValidator With the clientDateValidator tag, you can validate a child inputText element. The tag should be used to validate a date. The field displays a pop-up calendar. The validation is done on client side. validateAllOnClick With the validateAllOnClick tag, you can execute all client-side validation on the click of a specific element. That can be useful for a submit button. commandButton With the commandButton tag, it is possible to execute an arbitrary method on an instance. The method itself has to be a public method with no parameters and a java.lang.Object instance as the return value. commandLink The commandLink tag renders an AJAX link. With the processIds attribute, you can provide the ids of components which should be processed through the process. ajaxEvent The ajaxEvent tag creates a JavaScript event listener. This tag should only be used if you can ensure that the client has JavaScript enabled. A complete example After we have shown the main configuration elements and described the Spring Faces components, the following section shows a complete example in order to get a good understanding about how to work with the Spring Faces module in your own web application. The following diagram shows the screen of the sample application. With the shown screen, it is possible to create a new issue and save it to the bug database. It is not part of this example to describe the bug database or to describe how to work with databases in general. The sample uses the model classes. The diagram has three required fields. These fields are: Name: The name of the issue Description: A short description for the issue Fix until: The fixing date for the issue Additionally, there are the following two buttons: store: With a click on the store button, the system tries to create a new issue that includes the provided information cancel: With a click on the cancel button, the system ignores the data which is entered and navigates to the overview page. Now, the first step is to create the implementation of that input page. That implementation and its description are shown in the section below. Creating the input page As we described above, we use Facelets as a view handler technology. Therefore, the pages have to be defined with XHTML, with .xhtml as the file extension. The name for the input page will be add.xhtml. For the description, we separate the page into the following five parts: Header Name Description Fix until The Buttons This separation is shown in the diagram below: The Header part The first step in the header is to define that we have an XHTML page. This is done through the definition of the correct doctype. <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> An XHTML page is described as an XML page. If you want to use special tags inside the XML page, you have to define a namespace for that. For a page with Facelets and Spring Faces, we have to define more than one namespace. The following table describes those namespaces: Namespace Description http://www.w3.org/1999/xhtml The namespace for XHTML itself. http://java.sun.com/jsf/facelets The Facelet defines some components (tags). These components are available under this namespace. http://java.sun.com/jsf/html The user interface components of JSF are available under this namespace. http://java.sun.com/jsf/core The core tags of JSF, for example converter, can be accessed under this namespace. http://www.springframework.org/tags/faces The namespace for the Spring Faces component library. For the header definition, we use the composition component of the Facelets components. With that component, it is possible to define a template for the layout. This is very similar to the previously mentioned Tiles framework. The following code snippet shows you the second part (after the doctype) of the header definition: A description and overview of the JSF tags is available at: http://developers.sun.com/jscreator/archive/learning/bookshelf/pearson/corejsf/standard_jsf_tags.pdf. <ui:composition template="/WEB-INF/layouts/standard.xhtml"> With the help of the template attribute, we refer to the used layout template. In our example, we refer to /WEB-INF/layouts/standard.xhtml. The following code shows the complete layout file standard.xhtml. This layout file is also described with the Facelets technology. Therefore, it is possible to use Facelets components inside that page, too. Additionally, we use Spring Faces components inside that layout page. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html > <f:view contentType="text/html"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>flow.tracR</title> <sf:includeStyles/> <sf:resourceGroup> <sf:resource path="/css-framework/css/tools.css"/> <sf:resource path="/css-framework/css/typo.css"/> <sf:resource path="/css-framework/css/forms.css"/> <sf:resource path="/css-framework/css/layout-navtop-localleft. css"/> <sf:resource path="/css-framework/css/layout.css"/> </sf:resourceGroup> <sf:resource path="/css/issue.css"/> <ui:insert name="headIncludes"/> </head> <body class="tundra spring"> <div id="page"> <div id="content"> <div id="main"> <ui:insert name="content"/> </div> </div> </div> </body> </f:view> </html> The Name part The first element in the input page is the section for the input of the name. For the description of that section, we use elements from the JSF component library. We access this library with h as the prefix, which we have defined in the header section. For the general layout, we use standard HTML elements, such as the div element. The definition is shown below. <div class="field"> <div class="label"> <h:outputLabel for="name">Name:</h:outputLabel> </div> <div class="input"> <h:inputText id="name" value="#{issue.name}" /> </div> </div> The Description part The next element in the page is the Description element. The definition is very similar to the Name part. Instead of the definition of the Name part, we use the element description inside the h:inputText element—the required attribute with true as its value. This attribute tells the JSF system that the issue.description value is mandatory. If the user does not enter a value, the validation fails. <div class="field"> <div class="label"> <h:outputLabel for="description">Description:</h:outputLabel> </div> <div class="input"> <h:inputText id="description" value="#{issue.description}" required="true"/> </div> </div> The Fix until part The last input section is the Fix until part. This field is a very common field in web applications, because there is often the need to input a date. Internally, a date is often represented through an instance of the java.util.Date class. The text which is entered by the user has to be validated and converted in order to get a valid instance. To help the user with the input, a calendar for the input is often used. The Spring Faces library offers a component which shows a calendar and adds client-side validation. The complete definition of the Fix until part is shown below. The name of the component is clientDateValidator. The clientDateValidator component is used with sf as the prefix. This prefix is defined in the namespace definition in the shown header of the add.xhtml page. <div class="field"> <div class="label"> <h:outputLabel for="checkinDate">Fix until:</h:outputLabel> </div> <div class="input"> <sf:clientDateValidator required="true" invalidMessage="pleaseinsert a correct fixing date. format: dd.MM.yyyy"promptMessage="Format: dd.MM.yyyy, example: 01.01.2020"> <h:inputText id="checkinDate" value="#{issue.fixingDate}" required="true"> <f:convertDateTime pattern="dd.MM.yyyy" timeZone="GMT"/> </h:inputText> </sf:clientDateValidator> </div> </div> In the example above, we use the promptMessage attribute to help the user with the format. The message is shown when the user sets the cursor on the input element. If the validation fails, the message of the invalidMessage attribute is used to show the user that a wrong formatted input has been entered. The Buttons part The last element in the page are the buttons. For these buttons, the commandButton component from Spring Faces is used. The definition is shown below: <div class="buttonGroup"> <sf:commandButton id="store" action="store" processIds="*" value="store"/> <sf:commandButton id="cancel" action="cancel" processIds="*" value="cancel"/> </div> It is worth mentioning that JavaServer Faces binds an action to the action method of a backing bean. Spring Web Flow binds the action to events. Handling of errors It's possible to have validation on the client side or on the server side. For the Fix until element, we use the previously mentioned clientDateValidator component of the Spring Faces library. The following figure shows how this component shows the error message to the user: Reflecting the actions of the buttons into the flow definition file Clicking the buttons executes an action that has a transition as the result. The name of the action is expressed in the action attribute of the button component which is implemented as commandButton from the Spring Faces component library. If you click on the store button, the validation is executed first. If you want to prevent that validation, you have to use the bind attribute and set it to false. This feature is used for the cancel button, because in this state it is necessary to ignore the inputs. <view-state id="add" model="issue"> <transition on="store" to="issueStore" > <evaluate expression="persistenceContext.persist(issue)"/> </transition> <transition on="cancel" to="cancelInput" bind="false"> </transition> </view-state> Showing the results To test the implemented feature, we implement an overview page. We have the choice to implement the page as a flow with one view state or implement it as a simple JSF view. Independent from that choice, we will use Facelets to implement that overview page, because Facelets does not depend on the Spring Web Flow Framework as it is a feature of JSF. The example uses a table to show the entered issues. If no issue is entered, a message is shown to the user. The figure below shows this table with one row of data. The Id is a URL. If you click on this link, the input page is shown with the data of that issue. With data, we execute an update. The indicator for that is the valid ID of the issue. If your data is available, the No issues in database message is shown to the user. This is done with a condition on the outputText component. See the code snippet below: <h:outputText id="noIssuesText" value="No Issues in the database" rendered="#{empty issueList}"/> For the table, we use the dataTable component. <h:dataTable id="issues" value="#{issueList}" var="issue"rendered="#{not empty issueList}" border="1"> <h:column> <f:facet name="header">Id</f:facet> <a href="add?id=#{issue.id}">#{issue.id}</a> </h:column> <h:column> <f:facet name="header">Name</f:facet> #{issue.name} </h:column> <h:column> <f:facet name="header">fix until</f:facet> #{issue.fixingDate} </h:column> <h:column> <f:facet name="header">creation date</f:facet> #{issue.creationDate} </h:column> <h:column> <f:facet name="header">last modified</f:facet> #{issue.lastModified} </h:column> </h:dataTable>
Read more
  • 0
  • 0
  • 3234

article-image-extending-application-using-microsoft-dynamics-nav-2009-part-1
Packt
28 Oct 2009
11 min read
Save for later

Extending the Application using Microsoft Dynamics NAV 2009 (Part 1)

Packt
28 Oct 2009
11 min read
Learning to fish Give a man a fish and you feed him for a day; teach him to use the Internet, and he won't bother you for weeks! This is going to be a real challenge for the one that wants to play with the new technology that Web services enablement brings, but is a little unsure where to start. A good number of people that are experienced NAV consultants and C/AL developers are going to need to learn some new technologies if they want to start experimenting with the new extensibility options in Dynamics NAV 2009, or even simply understand what options are available for their new solution designs or sales presentations. This article is going to be all about practical examples—real sample applications that you can create for yourself. Some of these examples start off with one set of requirements that evolve as we progress through the design process. The examples are deliberately kept this way to help you to understand that the path to your final working solution is not always the shortest. Sometimes you get an idea for an application and as you proceed with the design, you think of things that would be better or easier to use. Sometimes your initial design simply won't work when you start to try it out. It's important to realize that designs are not precious and it's OK to change your mind. There are a couple of important issues to consider: always ensure you are solving the business problem, and don't get carried away gold-plating your design. Keep it simple, and once it is working and meets the initial requirements, you can then go back and add the bells and whistles (but you'd better check with whoever is paying the bills first). If you aren't a .NET programmer, and you have never created a web site or Web service in your life, this article is not a place to tell you the best way to do these things, but instead is a place to show you that with a very limited knowledge of .NET, a web browser to do some research, and enough time, you can create pretty much anything you can imagine. First of all, let's get some theory out of the way so that we have a basic understanding of what we're dealing with. What's a Web service? Web services have been around for a few years now but they are new to NAV (well, sort of— but more on that later). A good way to distinguish between technical and non-technical NAV consultants is to ask them if NAV supports Web services and watch to see if their eyes glaze over. There's no wonder some NAV consultants struggle to understand Web services as a concept; if you're not a developer and you have never worked with Web services, learning the basics might be more than a little bit scary. Here's a typical definition you might find on the Web; don't be put off by the geek-speak. A scary geeky definition of a Web service A 'Web service' (also Web Service) is defined by the W3C as 'a software system designed to support interoperable machine-to-machine interaction over a network'. Web services are frequently just Web APIs that can be accessed over a network, such as the Internet, and executed on a remote system hosting the requested services. There are a lot of acronyms and jargon phrases to learn if you want to talk the talk, but let's take a look at what a Web service is in simple terms. To start with, let's consider a comparison between web sites, something we are all familiar with, and Web services. One might like to think that a Web service is to a computer what a web site is to a person. If you want to know what's on TV tonight, you can type the URL for a TV Listings site into a web browser and bring up a page with details. It's not going to take you long to find the required information, but what if you wanted to write a computer program to send an e-mail when your favorite TV show was about to start, how would you go about that? This is a more complex problem, we know the data is there on the web site, freely available to all humans, but we can't just tell our computer to go off and read the web site (well we can—but deciphering it may require a fair amount of clever programming). Wouldn't it be great if there was a computer-friendly version of the data on the web site that allowed computers to ask for information and get answers back? Wouldn't it be great if you could write your program to make the call to this service without the need to install any special software components on your computer? Yes, it is great, and that's why Web services came into being and have now become so popular. It's not just for the Web It's not immediately obvious why we would want to expose our precious company data that we keep locked up in our ERP system on the Web, but just because they're called Web services doesn't mean they're just for the World Wide Web. Let's consider the intranet compared to the internet. It didn't take long for companies to realize that the popularity of internet sites and the ease of use that everyone was experiencing through the world wide web could provide great benefits within the boundaries of a company's safe internal network—a kind of mini-internal-internet or intranet. For Dynamics NAV, the analogy between Web Sites and Web services works even better when we consider an intranet. What if different departments could pull data directly from the ERP system and use it in their own specialist applications? This is where the real value of Web services enablement in Dynamics NAV 2009 comes into its own. It is now possible to take any functionality from within the ERP solution and expose it to other applications as Web services; it's not just possible, it's dead easy! What can we do with them? OK, so it's easy to expose NAV functionality, so what? Well if you can call any Codeunit or Page from within NAV with pretty much any software package that you can extend, there are limitless possibilities to create fantastic productivity applications for the business. Here are just a few examples: Let staff submit their expenses from Excel, or from their mobile phone, without needing to re-key them into the finance system. Allow users to create new customer accounts from within Word or from an intranet web page. Provide a Vista Sidebar gadget that shows the number of documents requiring approval and allows the user to approve the document without needing to open the ERP. Provide a simple single-task Windows application that will let staff see where stock is. These examples are just a few that spring immediately to mind, but if you have the know-how, you can do pretty much anything. So how easy is it to expose NAV functionality as a Web service? Let's find out. Calling a NAV Web service There is a great series of articles on MSDN by Manuel Oliveira that explain how to expose NAV functionality as a Web service. If you have never read these, you may want to skim through them after reading this example to see just how easy we have it with the new version of NAV. Talking with NAV—the hard way! Visit http://msdn.microsoft.com/en-us/library/ms952182.aspx and http://msdn.microsoft.com/en-us/library/ms952079.aspx for a couple of examples that explain the multiple hoops we needed to jump through in order to access NAV functionality using Web services. That's before NAV 2009 came along! Since these early examples of NAV extensibility, the Windows Communication Framework has made things easier, and Kris Rafnsson has provided a blog posting and sample application that allows you to call NAV functionality as a Web service without using message queues. This example is pretty amazing, but there is still a fair amount of work required to get this up and running and build new solutions. Although this is a big improvement on the Message Queue approach, it is nothing compared to the simplicity and elegance of the NAV 2009 Web services enablement. You can read through Kris's post at http://blogs.msdn.com/nav/archive/2008/04/15/using-web-services-toaccess-microsoft-dynamics-nav-5-0.aspx. In Manuel's first example (although not actually a Web service), he creates a simple NAV function that will accept a text string and return the text string back but converted to upper case. This example spans 15 printed pages and uses a lot of geeky stuff. As a bare minimum, we are going to need a Codeunit to expose and a .NET program to call the thing, so let's forget about these and just compare the components that are needed to take care of the plumbing: Microsoft Message Queue Navision Communication Component XMLDOM automation control Navision Application Server A lot of complicated C/AL code using InStreams and OutStreams and XML manipulation Manuel's examples were written in 2004 and, although they're very well written, the whole thing is just too hard! After reading the articles, you'll understand why there hasn't been a glut of NAV components on the market using Web services exposed by NAV. Our example by contrast requires the following (again ignoring the Codeunit we are exposing and the .NET program needed to call it): Dynamics NAV 2009 Business Web services A new record in a table with a check in a box Creating a Web service Let's start by creating our very simple Codeunit. In this example, I have created Codeunit 50001 called NAV Codeunit, which has a single function called ConvertStrToUpperCase that takes a 50 character text field and returns a 50 character text field that has been converted to upper case. It wasn't absolutely necessary for this example, but I put some code in the OnRun() trigger of the Codeunit that will demonstrate the Codeunit working when run. Here is the output from running the Codeunit in NAV: Now we can expose this Codeunit as a Web service. In the Classic client, select Administration | IT Administration | General Setup | Web Services. This is just a regular NAV form, so fill in the details on a new record with Object Type as Codeunit, Object ID as 50001, and Service Name as NAV Codeunit. To publish the Web service, tick the Published field. I just happened to give the Web service the same name as the Codeunit, but this is not necessary, you can call it whatever you like. We have now exposed NAV functionality as a Web service—how easy was that? Calling the Web service The .NET program to call the Web service is going to be a little harder. We're going to create a simple C# console application using Microsoft Visual Studio 2008 Professional Edition. (This is installed on the Marketing Beta release of the product which all partners can download from PartnerSource.) Create a new Console Application, let's call this one SayHelloToNAV2009. The project gets created with a Program.cs file with enough code generated for you to allow the project to compile and run. There's no way I can teach you to program in C# in this article, there are whole books dedicated to the subject; instead what I'll do is give you the details you need to be able to recreate our examples for yourself. If you like what you see, maybe you'll go on to do some more .NET programming and your next book will be one on C#. The great thing about .NET languages and Visual Studio is there's a huge amount of knowledge freely available on the Web. The first thing we need to do is add our Web service to the project. To do this, right-click on the References node in the Solution Explorer window and select Add Service Reference. Visual Studio 2005 is differentThese instructions are for adding a web reference using Visual Studio 2008. In 2005, things work a little differently. Instead of selecting References | Add Service Reference | Advanced | Add Web Reference, you simply selected Add Reference | Add Web Reference. In the dialog that is displayed, click the Advanced button, and then click the Add Web Reference button. In the Add Web Reference dialog form, enter http://nav-srv-01:7047/DynamicsNAV/ws/CRONUS_International_Ltd/Services as the URL for the Web service. This will display the group of Web services that are exposed by NAV. Where do I find that URL? The format of the URL is quite straightforward. Let's break it up into chunks.
Read more
  • 0
  • 0
  • 2791
article-image-using-business-rules-define-decision-points-oracle-soa-suite-part-2
Packt
28 Oct 2009
6 min read
Save for later

Using Business Rules to Define Decision Points in Oracle SOA Suite: Part 2

Packt
28 Oct 2009
6 min read
To invoke a rule we need to go through a number of steps. First we must create a session with the rules engine, then we can assert one or more facts, before executing the rule set and finally we can retrieve the results. We do this in BPEL via a Decision Service; this is essentially a web service wrapper around a rules dictionary, which takes cares of managing the session with the rules engine as well as governing which rule set we wish to apply. The wrapper allows a BPEL process to assert one or more facts, execute a rule set against the asserted facts, retrieve the results and then reset the session. This can be done within a single invocation of an operation, or over multiple operations. Creating a Rule Engine Connection Before you can create a Decision Service you need to create a connection to the repository in which the required rule set is stored. In the Connections panel within JDeveloper, right-click on the Rule Engines folder and select New Rule Engine Connection… as shown in the following screenshot: This will launch the Create Rule Engine Connection dialogue; first you need to specify whether the connection is for a file repository or WebDAV repository. Using a file based repository If you are using a file repository, all we need to specify is the location of the actual file. Once the connection has been created, we can use this to create a decision service for any of the rule sets contained within that repository. However, it is important to realize that when you create a decision service based on this connection, JDeveloper will take a copy of the repository and copy this into the BPEL project. When you deploy the BPEL process, then the copy of this repository will be deployed with the BPEL process. This has a number of implications; first if you want to modify the rule set used by the BPEL Process you need to modify the copy of the repository deployed with the BPEL Process. To modify the rule set deployed with a BPEL Process, log onto the BPEL console, from here click on the BPEL Processes tab, and then select the process that uses the decision service. Next click on the Descriptor tab; this will list all the Partner Links for that process, including the Decision Service (for example LeaveApprovalDecisionServicePL) as shown in the following screenshot: This PartnerLink will have the property decisionServiceDetails, with the link Rule Service Details (circled in the previous screenshot); click on this and the console will display details of the decision service. From here click on the link Open Rule Author; this will open the Rule Author complete with a connection to the file based rule repository. The second implication is that if you use the same rule set within multiple BPEL Processes, each process will have its own copy of the rule set. You can work round this by either wrapping each rule set with a single BPEL process, which is then invoked by any other process wishing to use that rule set. Or once you have deployed the rule set for one process, then you can access it directly via the WSDL for the deployed rule set, for example LeaveApprovalDecisionService.wsdl in the above screenshot. Using a WebDAV repository For the reasons mentioned above, it often makes sense to use a WebDAV based repository to hold your rules. This makes it far simpler to share a rule set between multiple clients, such as BPEL and Java. Before you can create a Rule Engine Connection to a WebDAV repository, you must first define a WebDAV connection to JDeveloper, which is also created from the Connections palette. Creating a Decision Service To create a decision service within our BPEL process, select the Services page from the Component Palette and drag a Decision Service onto your process, as shown in the following screenshot: This will launch the Decision Service Wizard dialogue, as shown: Give the service a name, and then select Execute Ruleset as the invocation pattern. Next click on the flashlight next to Ruleset to launch the Rule Explorer. This allows us to browse any previously defined rule engine connection and select the rule set we wish to invoke via the decision service. For our purposes, select the LeaveApprovalRules as shown below, and click OK. This will bring us back to the Decision Service Wizard which will be updated to list the facts that we can exchange with the Rule Engine, as shown in the following screenshot: This dialogue will only list XML Facts that map to global elements in the XML Schema. Here we need to define which facts we want to assert, that is which facts we pass as inputs to the rule engine from BPEL, and which facts we want to watch, that is which facts we want to return in the output from the rules engine back to our BPEL process. For our example, we will pass in a single leave request. The rule engine will then apply the rule set we defined earlier and update the status of the request to Approved if appropriate. So we need to specify that Assert and Watch facts of type LeaveRequest. Finally, you will notice the checkbox Check here to assert all descendants from the top level element; this is important when an element contains nested elements (or facts) to ensure that nested facts are also evaluated by the rules engine. For example if we had a fact of type LeaveRequestList which contained a list of multiple LeaveRequests, if we wanted to ensure the rules engine evaluated these nested facts, then we would need to check this checkbox. Once you have specified the facts to Assert and Watch, click Next and complete the dialogue; this will then create a decision service partner link within your BPEL process. Adding a Decide activity We are now ready to invoke our rule set from within our BPEL process. From the Component Palette, drag a Decide activity onto our BPEL process (at the point before we execute the LeaveRequest Human Task). This will open up the Edit Decide window (shown in the following screenshot). Here we need to specify a Name for the activity, and select the Decision Service we want to invoke (that is the LeaveApprovalDecisionService that we just created). Once we've specified the service, we need to specify how we want to interact with it. For example, whether we want to incrementally assert a number of facts over a period of time, before executing the rule set and retrieving the result or whether we want to assert all the facts, execute the rule set and get the result within a single invocation. We specify this through the Operation attribute. For our purpose we just need to assert a single fact and run the rule set, so select the value of Assert facts, execute rule set, retrieve results. Once we have selected the operation to invoke on the decision service, the Decision Service Facts will be updated to allow you to assign input and output facts as appropriate.  
Read more
  • 0
  • 0
  • 2151

article-image-working-complex-associations-using-cakephp
Packt
28 Oct 2009
6 min read
Save for later

Working with Complex Associations using CakePHP

Packt
28 Oct 2009
6 min read
Defining Many-To-Many Relationship in Models In the previous article in this series on Working with Simple Associations using CakePHP, we assumed that a book can have only one author. But in real life scenario, a book may also have more than one author. In that case, the relation between authors and books is many-to-many. We are now going to see how to define associations for a many-to-many relation. We will modify our existing code-base that we were working on in the previous article to set up the associations needed to represent a many-to-many relation. Time for Action: Defining Many-To-Many Relation Empty the database tables: TRUNCATE TABLE `authors`;TRUNCATE TABLE `books`; Remove the author_id field from the books table: ALTER TABLE `books` DROP `author_id` Create a new table, authors_books:; CREATE TABLE `authors_books` (`author_id` INT NOT NULL ,`book_id` INT NOT NULL Modify the Author (/app/models/author.php) model: <?phpclass Author extends AppModel{ var $name = 'Author'; var $hasAndBelongsToMany = 'Book';}?> Modify the Book (/app/models/book.php) model: <?phpclass Book extends AppModel{ var $name = 'Book'; var $hasAndBelongsToMany = 'Author';}?> Modify the AuthorsController (/app/controllers/authors_controller.php): <?phpclass AuthorsController extends AppController { var $name = 'Authors'; var $scaffold;}?> Modify the BooksController (/app/controllers/books_controller.php): <?phpclass BooksController extends AppController { var $name = 'Books'; var $scaffold;}?> Now, visit the following URLs and add some test data into the system:http://localhost/relationship/authors/ and http://localhost/relationship/books/ What Just Happened? We first emptied the database and then dropped the field author_id from the books table. Then we added a new join table authors_books that will be used to establish a many-to-many relation between authors and books. The following diagram shows how a join table relates two tables in many-to-many relation: In a many-to-many relation, one record of any of the tables can be related to multiple records of the other table. To establish this link, a join table is used—a join table contains two fields to hold the primary-keys of both of the records in relation. CakePHP has certain conventions for naming a join table—join tables should be named after the tables in relation, in alphabetical order, with underscores in between. The join table between authors and books tables should be named authors_books, not books_authors. Also by Cake convention, the default value for the foreign keys used in the join table must be underscored, singular name of the models in relation, suffixed with _id. After creating the join table, we defined associations in the models, so that our models also know about the new relationship that they have. We added hasAndBelongsToMany (HABTM) associations in both of the models. HABTM is a special type of association used to define a many-to-many relation in models. Both the models have HABTM associations to define the many-to-many relationship from both ends. After defining the associations in the models, we created two controllers for these two models and put in scaffolding in them to see the association working. We could also use an array to set up the HABTM association in the models. Following code segment shows how to use an array for setting up an HABTM association between authors and books in the Author model: var $hasAndBelongsToMany = array( 'Book' => array( 'className' => 'Book', 'joinTable' => 'authors_books', 'foreignKey' => 'author_id', 'associationForeignKey' => 'book_id' ) ); Like, simple relationships, we can also override default association characteristics by adding/modifying key/value pairs in the associative array. The foreignKey key/value pair holds the name of the foreign-key found in the current model—default is underscored, singular name of the current model suffixed with _id. Whereas, associationForeignKey key/value pair holds the foreign-key name found in the corresponding table of the other model—default is underscored, singular name of the associated model suffixed with _id. We can also have conditions, fields, and order key/value pairs to customize the relationship in more detail. Retrieving Related Model Data in Many-To-Many Relation Like one-to-one and one-to-many relations, once the associations are defined, CakePHP will automatically fetch the related data in many-to-many relation. Time for Action: Retrieving Related Model Data Take out scaffolding from both of the controllers—AuthorsController (/app/controllers/authors_controller.php) and BooksController (/app/controllers/books_controller.php). Add an index() action inside the AuthorsController (/app/controllers/authors_controller.php), like the following: <?phpclass AuthorsController extends AppController { var $name = 'Authors'; function index() { $this->Author->recursive = 1; $authors = $this->Author->find('all'); $this->set('authors', $authors); }}?> Create a view file for the /authors/index action (/app/views/authors/index.ctp): <?php foreach($authors as $author): ?><h2><?php echo $author['Author']['name'] ?></h2><hr /><h3>Book(s):</h3><ul><?php foreach($author['Book'] as $book): ?><li><?php echo $book['title'] ?></li><?php endforeach; ?></ul><?php endforeach; ?> Write down the following code inside the BooksController (/app/controllers/books_controller.php): <?phpclass BooksController extends AppController { var $name = 'Books'; function index() { $this->Book->recursive = 1; $books = $this->Book->find('all'); $this->set('books', $books); }}?> Create a view file for the action /books/index (/app/views/books/index.ctp): <?php foreach($books as $book): ?><h2><?php echo $book['Book']['title'] ?></h2><hr /><h3>Author(s):</h3><ul><?php foreach($book['Author'] as $author): ?><li><?php echo $author['name'] ?></li><?php endforeach; ?></ul><?php endforeach; ?> Now, visit the following URLs:http://localhost/relationship/authors/http://localhost/relationship/books/ What Just Happened? In both of the models, we first set the value of $recursive attributes to 1 and then we called the respective models find('all') functions. So, these subsequent find('all') operations return all associated model data that are related directly to the respective models. These returned results of the find('all') requests are then passed to the corresponding view files. In the view files, we looped through the returned results and printed out the models and their related data. In the BooksController, this returned data from find('all') is stored in a variable $books. This find('all') returns an array of books and every element of that array contains information about one book and its related authors. Array ( [0] => Array ( [Book] => Array ( [id] => 1 [title] => Book Title ... ) [Author] => Array ( [0] => Array ( [id] => 1 [name] => Author Name ... ) [1] => Array ( [id] => 3 ... 54 54 ... ...) Same for the Author model, the returned data is an array of authors. Every element of that array contains two arrays: one contains the author information and the other contains an array of books related to this author. These arrays are very much like what we got from a find('all') call in case of the hasMany association.
Read more
  • 0
  • 0
  • 7049

article-image-working-xml-flex-3-and-java-part2
Packt
28 Oct 2009
7 min read
Save for later

Working with XML in Flex 3 and Java-part2

Packt
28 Oct 2009
7 min read
  Loading external XML documents You can use the URLLoader class to load external data from a URL. The URLLoader class downloads data from a URL as text or binary data. In this section, we will see how to use the URLLoader class for loading external XML data into your application. You can create a URLLoader class instance and call the load() method by passing URLRequest as a parameter and register for its complete event to handle loaded data. The following code snippet shows how exactly this works: private var xmlUrl:String = "http://www.foo.com/rssdata.xml";private var request:URLRequest = new URLRequest(xmlUrl);private var loader:URLLoader = new URLLoader(;private var rssData:XML;loader.addEventListener(Event.COMPLETE, completeHandler);loader.load(request);private function completeHandler(event:Event):void { rssData = XML(loader.data); trace(rssData);} Let's see one quick complete sample of loading RSS data from the Internet: <?xml version="1.0" encoding="utf-8"?><mx:Application creationComplete="loadData();"> <mx:Script> <![CDATA[ import mx.collections.XMLListCollection; private var xmlUrl:String = "http://sessions.adobe.com/360FlexSJ2008/feed.xml"; private var request:URLRequest = new URLRequest(xmlUrl); private var loader:URLLoader = new URLLoader(request); [Bindable] private var rssData:XML; private function loadData():void { loader.addEventListener(Event.COMPLETE, completeHandler); loader.load(request); } private function completeHandler(event:Event):void { rssData = new XML(loader.data); } ]]></mx:Script><mx:Panel title="RSS Feed Reader" width="100%" height="100%"> <mx:DataGrid id="dgGrid" dataProvider="{rssData.channel.item}" height="100%" width="100%"> <mx:columns> <mx:DataGridColumn headerText="Title" dataField="title"/> <mx:DataGridColumn headerText="Link" dataField="link"/> <mx:DataGridColumn headerText="pubDate" dataField="pubDate"/> <mx:DataGridColumn headerText="Description" dataField="description"/> </mx:columns></mx:DataGrid><mx:TextArea width="100%" height="80" text="{dgGrid.selectedItem.description}"/></mx:Panel></mx:Application> In the code above, we are loading RSS feed from an external URL and displaying it in DataGrid by using data binding. Output: An example: Building a book explorer In this section, we will build something more complicated and interesting by using many features, including custom components, events, data binding, E4X, loading external XML data, and so on. We will build a sample books explorer, which will load a books catalog from an external XML file and allow the users to explore and view details of books. We will also build a simple shopping cart component, which will list books that a user would add to cart by clicking on the Add to cart button. Create a new Flex project using Flex Builder. Once the project is created, create an assetsimages folder under its src folder. This folder will be used to store images used in this application. Now start creating the following source files into its source folder. Let's start by creating a simple book catalog XML file as follows: bookscatalog.xml:<books> <book ISBN="184719530X"> <title>Building Websites with Joomla! 1.5</title> <author> <lastName>Hagen</lastName> <firstName>Graf</firstName> </author> <image>../assets/images/184719530X.png</image> <pageCount>363</pageCount> <price>Rs.1,247.40</price> <description>The best-selling Joomla! tutorial guide updated for the latest 1.5 release </description> </book> <book ISBN="1847196160"> <title>Drupal 6 JavaScript and jQuery</title> <author> <lastName>Matt</lastName> <firstName>Butcher</firstName> </author> <image>../assets/images/1847196160.png</image> <pageCount>250</pageCount> <price>Rs.1,108.80</price> <description>Putting jQuery, AJAX, and JavaScript effects into your Drupal 6 modules and themes</description> </book> <book ISBN="184719494X"> <title>Expert Python Programming</title> <author> <lastName>Tarek</lastName> <firstName>Ziadé</firstName> </author> <image>../assets/images/184719494X.png</image> <pageCount>350</pageCount> <price>Rs.1,247.4</price> <description>Best practices for designing, coding, and distributing your Python software</description> </book> <book ISBN="1847194885"> <title>Joomla! Web Security</title> <author> <lastName>Tom</lastName> <firstName>Canavan</firstName> </author> <image>../assets/images/1847194885.png</image> <pageCount>248</pageCount> <price>Rs.1,108.80</price> <description>Secure your Joomla! website from common security threats with this easy-to-use guide</description> </book></books> The above XML file contains details of individual books in an XML form. You can also deploy this file on your web server and specify its URL into URLRequest while loading it. Next, we will create a custom event which we will be dispatching from our custom component. Make sure you create an events package under your src folder in Flex Builder called events, and place this file in it. AddToCartEvent.as:package events{ import flash.events.Event; public class AddToCartEvent extends Event { public static const ADD_TO_CART:String = "addToCart"; public var book:Object; public function AddToCartEvent(type:String, bubbles_Boolean=false, cancelable_Boolean=false) { super(type, bubbles, cancelable); } }} This is a simple custom event created by inheriting the flash.events.Event class. This class defines the ADD_TO_CART string constant, which will be used as the name of the event in the addEventListener() method. You will see this in the BooksExplorer.mxml code. We have also defined an object to hold the reference of the book which the user can add into the shopping cart. In short, this object will hold the XML node of a selected book. Next, we will create the MXML custom component called BookDetailItemRenderer.mxml. Make sure that you create a package under your src folder in Flex Builder called components, and place this file in it and copy the following code in it: <?xml version="1.0" encoding="utf-8"?><mx:HBox cornerRadius="8" paddingBottom="2" paddingLeft="2"paddingRight="2" paddingTop="2"><mx:Metadata>[Event(name="addToCart", type="flash.events.Event")]</mx:Metadata><mx:Script><![CDATA[import events.AddToCartEvent;import mx.controls.Alert;[Bindable][Embed(source="../assets/images/cart.gif")]public var cartImage:Class;private function addToCardEventDispatcher():void {var addToCartEvent:AddToCartEvent = new AddToCartEvent("addToCart", true, true);addtoCartEvent.book = data;dispatchEvent(addtoCartEvent);}]]></mx:Script><mx:HBox width="100%" verticalAlign="middle" paddingBottom="2"paddingLeft="2" paddingRight="2" paddingTop="2" height="100%"borderStyle="solid" borderThickness="2" borderColor="#6E6B6B"cornerRadius="4"><mx:Image id="bookImage" source="{data.image}" height="109"width="78" maintainAspectRatio="false"/><mx:VBox height="100%" width="100%" verticalGap="2"paddingBottom="0" paddingLeft="0" paddingRight="0"paddingTop="0" verticalAlign="middle"><mx:Label id="bookTitle" text="{data.title}"fontSize="12" fontWeight="bold"/><mx:Label id="bookAuthor" text="By: {data.author.lastName},{data.author.firstName}" fontWeight="bold"/><mx:Label id="coverPrice" text="Price: {data.price}"fontWeight="bold"/><mx:Label id="pageCount" text="Pages: {data.pageCount}"fontWeight="bold"/><mx:HBox width="100%" backgroundColor="#3A478D"horizontalAlign="right" paddingBottom="0" paddingLeft="0"paddingRight="5" paddingTop="0" height="22"verticalAlign="middle"><mx:Label text="Add to cart " color="#FFFFFF"fontWeight="bold"/><mx:Button icon="{cartImage}" height="20" width="20"click="addToCardEventDispatcher();"/></mx:HBox></mx:VBox></mx:HBox></mx:HBox>
Read more
  • 0
  • 0
  • 2014
article-image-scalix-and-security
Packt
28 Oct 2009
7 min read
Save for later

Scalix and Security

Packt
28 Oct 2009
7 min read
Basic Security and Firewalls An administrator installing a Scalix server in a productive environment must make some considerations before setting up his system: Is the server accessible from the Internet? Is the server accessible to untrusted users? Who must access Scalix? Who must access administration? Who must be prevented from gaining access? Which services must be accessible from where? Though this may sound theoretical, such thoughts always play an important role when you are planning any productive server. In most cases, there are only three different setups for a groupware server: There are only local users in the company's network and the server is located in the company. There are local users and remote users connecting to the Scalix server located in the company. There are both local and remote users connecting to the Scalix server located on the Internet. While the installation leaves a perfectly configured system that is stable, there are several possible precautions that should be taken when your Scalix server is accessible from the Internet — the access should be controlled by a firewall, connections should be encrypted, and users must be forced to use strong authentication mechanisms. As always, there are several ways to achieve this. Before we start, here is a list of services that have to be available for Scalix users accessing the server remotely:- SSH: TCP port 22, the standard remote administration for the admin. SMTP: TCP port 25 — Sending mail. IMAP: TCP port 143 — Retrieving mail with the IMAP protocol. POP: TCP port 110 —  Retrieving mail with the POP protocol. HTTP: TCP port 80: Accessing the Web interface. Scalix UAL uses port 5287 And as of 11.3, secure UAL connects over 5767 Linux Firewall Terminology Basically speaking, a firewall is a piece of software that controls internet connections to and from a server. SUSE's Linux systems come with a built-in firewall named SUSEfirewall that can easily be configured with YaST. On Red Hat Linux systems, there is Bastille and firewall GUIs like Shorewall, which are all good choices for any Linux system. All common Linux firewalls are based on iptables or its predecessor ipchains. Its concept is pretty simple: the administrator defines a chain of rules that are worked through by the operating system one after another for every incoming or outgoing connection or package. So-called targets define what to do with packages matching the rule specified. Targets may be, for example, Accept, Reject, Drop or Log. Furthermore, there are policies that define the default behavior for connections where no rule matches. The Linux program iptables controls these rules. A little glance on this tool may help understanding how a Linux firewall works. iptables—the Standard Linux Firewall Tool iptables (http://www.netfilter.org) is a simple command-line tool that controls the kernels' IP tables. In these tables, rules that define how network packets are treated on this system can be stored. As always, the simple commands offer the best solutions when they are combined with an abundance of options. There is a vast amount of options and extensions for iptables, so this short description is far from perfect and far from complete. The iptables syntax is very simple: iptables <rule command> <chain> <matching extensions><target> A typical rule command is A, which means Add the following rule. Since iptables use different chains (by default, INPUT, FORWARD, OUTPUT), we must declare a chain where this rule is to be added to. The following table shows three examples: Iptables Command Function: iptables -A INPUT <rule> Adds a rule to the INPUT chain, which affects all incoming packets heading for the firewall itself. iptables -A OUTPUT <rule> Adds a rule to the FORWARD chain, which affects all packets that are supposed to be forwarded by the firewall. iptables -A FORWARD <rule> Adds a rule to the OUTPUT chain, which affects all outgoing packets originating from the firewall. Another typical command is -P that sets the default policy for a chain. This should always be set to DROP, because then all packets arriving in this chain are dropped if not specified explicitly by another rule. This is the only way to make sure that only the traffic allowed by us is handled and any unspecified traffic is dropped. A typical example for this is: scalixbook:~ # iptables -P FORWARD DROPscalixbook:~ # This would prevent your system from forwarding any traffic, unless specified otherwise, later on. Then there are iptables' targets. A target can be either DROP, REJECT or ACCEPT (among others) and is invoked by the switch — j. Furthermore, so-called "matching extensions" are like a filter specifying exactly which packet is meant. Thus a rule like iptables -A INPUT <matching extension> -j DROP  means: Drop every packet that is headed for my firewall and matches the <matching extension>. Matching Extension Meaning -i <interface> The incoming interface of the datagram -o <interface> The outgoing interface of the datagram -p <protocol> The IP protocol of the datagram --dport <destination port> The destination port of the datagram --sport <source port> The source port of the datagram -s <source IP> The source IP of the sender -d <destination IP> The destination IP of the recipient There are many other matching extensions, but these here should be sufficient to understand the basics of iptables. Have a look at these lines: #!/bin/bashiptables -P INPUT DROPiptables -P OUTPUT DROPiptables -P FORWARD DROPiptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPTiptables -A INPUT -i eth0 -p tcp --dport 25 -j ACCEPTiptables -A INPUT -i eth0 -p tcp --dport 143 -j ACCEPTiptables -A OUTPUT -o eth0 -p tcp --sport 22 -j ACCEPTiptables -A OUTPUT -o eth0 -p tcp --dport 25 -j ACCEPTiptables -A OUTPUT -o eth0 -p tcp --dport 143 -j ACCEPT(...) Do you already understand them? If you do, congratulations; if not, don't worry, it's easy. These lines represent a shell script that can be used to start a very simple firewall example. iptables is a command-line tool and therefore is simply called from a script with parameters like the following: Command Meaning iptables -P INPUT DROP Drop all incoming packets that are not specified by any other rule iptables -P OUTPUT DROP Drop all outgoing packets that are not specified by any other rule iptables -P FORWARD DROP Do not forward any packets that are not specified by any other rule iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT Accept TCP connections for port 22 (SSH) coming in on network interface eth0 iptables -A INPUT -i eth0 -p tcp --dport 25 -j ACCEPT Accept TCP connections for port 25 (SMTP) coming in on network interface eth0 iptables -A INPUT -i eth0 -p tcp --dport 143 -j ACCEPT Accept TCP connections for port 143 (IMAP) coming in on network interface eth0 iptables -A OUTPUT -o eth0 -p tcp --sport 22 -j ACCEPT Accept outgoing TCP connections for port 22 going out on network interface eth0 iptables -A OUTPUT -o eth0 -p tcp --dport 25 -j ACCEPT Accept outgoing TCP connections for port 25 going out on network interface eth0 iptables -A OUTPUT -o eth0 -p tcp --dport 143 -j ACCEPT Accept outgoing TCP connections for port 143 going out on network interface eth0
Read more
  • 0
  • 0
  • 1806

article-image-elgg-social-networking-installation
Packt
28 Oct 2009
14 min read
Save for later

Elgg Social Networking - Installation

Packt
28 Oct 2009
14 min read
Installing Elgg In addition to its impressive feature list, Elgg is an admin's dolly. In this tutorial by Mayank Sharma, we will see how Elgg can be installed in popular Linux web application rollout stack of Linux, Apache, MySQL, and PHP, fondly referred to as LAMP. As MySQL and PHP can run under Windows operating system as well, you can set up Elgg to serve your purpose for such an environment. Setting Up LAMP Let's look at setting up the Linux, Apache, MySQL, PHP web server environment. There are several reasons for the LAMP stack's popularity. While most people enjoy the freedom offered by these Open Source software, small business and non-profits will also be impressed by its procurement cost—$0. Step 1: Install Linux The critical difference between setting up Elgg under Windows or Linux is installing the operating system. The Linux distribution I'm using to set up Elgg is Ubuntu Linux ( http://www.ubuntu.com/ ).It's available as a free download and has a huge and active global community, should you run into any problems. Covering step-by-step installation of Ubuntu Linux is too much of a digression for this tutorial. Despite the fact that Ubuntu isn't too difficult to install, because of its popularity there are tons of installation and usage documentation available all over the Web. Linux.com has a set of videos that detail the procedure of installing Ubuntu ( http://www.linux.com/articles/114152 ).Ubuntu has a dedicated help section ( https://help.ubuntu.com/ ) for introduction and general usage of the distribution. Step 2: Install Apache Apache is the most popular web server used on the Internet. Reams and reams of documents have been written on installing Apache under Linux. Apache's documentation sub-project ( http://httpd.apache.org/docs-project/ ) has information on installing various versions of Apache under Linux. Ubuntu, based on another popular Linux distribution, Debian, uses a very powerful and user-friendly packaging system. It's called apt-get and can install an Apache server within minutes. All you have to do is open a terminal and write this command telling apt-get what to install: apt-get install apache2 apache2-common apache2-doc apache2-mpm-prefork apache2-utils libapr0 libexpat1 ssl-cert This will download Apache and its most essential libraries. Next, you need to enable some of Apache's most critical modules: a2enmod ssla2enmod rewritea2enmod include The rewrite module is critical to Elgg, so make sure it's enabled, else Elgg wouldn't work properly. That's it. Now, just restart Apache with: /etc/init.d/apache2 restart. Step 3: MySQL Installing MySQL isn't too much of an issue either. Again, like Ubuntu and Apache, MySQL can also boast of a strong and dedicated community. This means there's no dearth of MySQL installation or usage related documentation ( http://www.mysql.org/doc/ ). If you're using MySQL under Ubuntu, like me, installation is just a matter of giving apt-get a set of packages to install: apt-get install mysql-server mysql-client libmysqlclient12-dev Finally, set up a password for MySQL with: mysqladmin -h yourserver.example.com -u root password yourrootmysqlpassword Step 4: Install PHP Support You might think I am exaggerating things a little bit here, but I am not, PHP is one of the most popular and easy to learn languages for writing web applications. Why do you think we are setting up out Linux web server environment to execute PHP? It's because Elgg itself is written in PHP! And so are hundreds and thousands of other web applications. So I'm sure you've guessed by now that PHP has a good deal of documentation ( http://www.php.net/docs.php )as well. You've also guessed it's now time to call upon Ubuntu's apt-get package manager to set up PHP:  apt-get install libapache2-mod-php5 php5 php5-common php5-gd php5-mysql php5-mysqli As you can see, in addition to PHP, we are also installing packages that'll hook up PHP with the MySQL database and the Apache web server. That's all there is to setting up the LAMP architecture to power your Elgg network. Setting Up WAMP If you are used to Microsoft's Windows operating system or want to avoid the extra minor learning curve involved with setting up the web server on a Linux distribution, especially, if you haven't done it before, you can easily replicate the Apache, MySQL, PHP web server on a Windows machine. Cost wise, all server components the Apache web server, MySQL database, and the PHP development language have freely available Windows versions as well. But the base component of this stack, the operating system —Microsoft Windows, isn't. Versions of Apache, MySQL, and PHP for Windows are all available on the same websites mentioned above. As Windows doesn't have an apt-get kind of utility, you'll have to download and install all three components from their respective websites, but you have an easier way to set up a WAMP server. There are several pre-packaged Apache, MySQL, and PHP software bundles available for Windows(http://en.wikipedia.org/wiki/Comparison_of_WAMPs).I've successfully run Elgg on the WAMP5 bundle (http://www.en.wampserver.com/). The developer updates the bundle, time and again, to make sure it's running the latest versions of all server components included in the bundle. Note - While WAMP5 requires no configuration, make sure you have Apache's rewrite_module and PHP's php_gd2 extension enabled. They will have a bullet next to their name if they are enabled. If the bullet is missing, click on the respective entries under the Apache and PHP sub-categories and restart WAMP5. Installing Elgg Now that we have a platform ready for Elgg, let's move on to the most important step of setting up Elgg. Download the latest version of Elgg from its website. At the time of writing this tutorial, the latest version of Elgg was Elgg-0.8. Elgg is distributed as a zipped file. To uncompress under Linux: Move this zipped file to /tmp and uncompress it with the following command: $ unzip /tmp/elgg-0.8.zip To uncompress under Windows: Right-click on the ZIP file and select the Extract here option. After uncompressing the ZIP file, you should have a directory called Elgg-<version-number>, in my case, elgg-0.8/. This directory contains several sub directories and files. The INSTALL file contains detailed installation instructions. The first step is to move this uncompressed directory to your web server. Note: You can set up Elgg on your local web server that sits on the Internet or on a paid web server in a data center anywhere on the planet. The only difference between the two setups is that if you don't have access to the local web server, you'll have to contact the web service provider and ask him about the transfer options available to you. Most probably, you'll have FTP access to your web server, and you'll have to use one of the dozens of FTP clients, available for free, to transfer Elgg's files from your computer to the remote web server. Optionally, if you have "shell" access on the web server, you might want to save time by transferring just the zipped file and unzipping it on the web server itself. Contact your web server provider for this information. The web server's directory where you need to copy the contents of the Elgg directory depends upon your Apache installation and operating system. In Ubuntu Linux, the default web server directory is /var/www/. In Windows, WAMP5 asks where it should create this directory during installation. By default, it's the www directory and is created within the directory you installed WAMP5 under. Note: Another important decision you need to make while installing Elgg is how do you want your users to access your network. If you're setting up the network to be part of your existing web infrastructure, you'll need to install Elgg inside a directory. If, on the other hand, you are setting up a new site just for the Elgg-powered social network, copy the contents of the Elgg directory inside the www directory itself and not within a subdirectory. Once you have the Elgg directory within your web server's www directory, it's time to set things in motion. Start by renaming the config-dist.php file to config.php and the htaccess-dist to .htaccess. Simply right-click on the file and give it a new name or use the mv command in this format: $ mv <original-file-name> <new-file-name> Note : To rename htacces-dist to .htaccess in Windows, you'll have to open the htaccess-dist file in notepad and then go to File | Save As and specify the name as .htaccess with the quotes. Editing config.php Believe it or not, we've completed the "installation" bit of setting up Elgg. But we still need to configure it before throwing the doors open to visitors. Not surprisingly, all this involves is creating a database and editing the config.php file to our liking. Creating a Database Making an empty database in MySQL isn't difficult at all. Just enter the MySQL interactive shell using your username, password, and hostname you specified while installing MySQL. $ mysql -u root -h localhost -pEnter password: Welcome to the MySQL monitor. Commands end with ; or g.Your MySQL connection id is 9 to server version: 5.0.22-Debian_0ubuntu6.06.3-logType 'help;' or 'h' for help. Type 'c' to clear the buffer.mysql> CREATE DATABASE elgg; You can also create a MySQL database using a graphical front-end manager like PHPMyAdmin, which comes with WAMP5. Just look for a database field, enter a new name (Elgg), and hit the Create button to create an empty Elgg database. Initial Configuration Elgg has a front-end interface to set up config.php, but there are a couple of things you need to do before you can use that interface: Create a data directory outside your web server root. As described in the configuration file, this is a special directory where uploaded files will go. It's also advisable to create this directory outside your main Elgg install. This is because this directory will be writable by everyone accessing the Elgg site and having such a "world-accessible" directory under your Elgg installation is a security risk. If you call the directory Elgg-data, make it world-readable with the following command: $ chmod 777 elgg-data Setup admin username and password. Before you can access Elgg's configuration web front-end, you need an admin user and a password. For that open the config.php file in your favorite text editor and scroll down to the following variables: $CFG->adminuser = "";$CFG->adminpassword = ""; Specify your chosen admin username and password between the quotes, so that it looks something like this: $CFG->adminuser = "admin";$CFG->adminpassword = "765thyr3"; Make sure you don't forget the username and password of the admin user. Important Settings When you have created the data directory and specified an admin username and password, it's time to go ahead with the rest of the configuration. Open a web browser and point to http://<your-web-server>/<Elgg-installation>/elggadmin/ This will open up a simple web page with lots of fields. All fields have a title and a brief description of the kind of information you need to fill in that field. There are some drop-down lists as well, from which you have to select one of the listed options. Here are all the options and their descriptions: Administration panel username: Username to log in to this admin panel, in future, to change your settings. Admin password: Password to log in to this admin panel in future. Site name: Enter the name of your site here (e.g. Elgg, Apcala, University of Bogton's Social Network, etc.). Tagline: A tagline for your site (e.g. Social network for Bogton). Web root: External URL to the site (e.g. http://elgg.bogton.edu/). Elgg install root: Physical path to the files (e.g./home/Elggserver/httpdocs/). Elgg data root: This is a special directory where uploaded files will go. If possible, this should live outside your main Elgg installation? (you'll need to create it by hand). It must have world writable permissions set, and have a final slash at the end. Note: Even in Windows, where we use back slashes () to separate directories, use Unix's forward slashes (/) to specify the path to the install root, data root, and other path names. For example, if you have Elgg files under WAMP's default directory in your C drive, use this path: C:/wamp/www/elgg/. Database type: Acceptable values are mysql and postgres - MySQL is highly recommended. System administrator email: The email address your site will send emails from(e.g. elgg-admin@bogton.edu). News account initial password: The initial password for the 'news' account. This will be the first administrator user within your system, and you should change the password immediately after the first time you log in. Default locale: Country code to set language to if you have gettext installed. Public registration: Can general members of the public register for this system? Public invitations: Can users of this system invite other users? Maximum users: The maximum number of users in your system. If you set this to 0, you will have an unlimited number of users. Maximum disk space: The maximum disk space taken up by all uploaded files. Disable public comments: Set the following to true to force users to log in before they can post comments, overriding the per-user option. This is a handy sledgehammer-to-crack-a-nut tactic to protect against comment spam (although an Akismet plug-in is available from elgg.org). Email filter: Anything you enter here must be present in the email address of anyone who registers; e.g. @mycompany.com will only allow email address from mycompany.com to register. Default access: The default access level for all new items in the system. Disable user templates: If this is set, users can only choose from available templates rather than defining their own. Persistent connections: Should Elgg use persistent database connections? Debug: Set this to 2047 to get ADOdb error handling. RSS posts maximum age: Number of days for which to keep incoming RSS feed entries before deleting them. Set this to 0 if you don't want RSS posts to be removed. Community create flag: Set this to admin if you would like to restrict the ability to create communities to admin users. cURL path: Set this to the cURL executable if cURL is installed; otherwise leave blank. Note : According to Wikipedia, cURL is a command line tool for transferring files with URL syntax, supporting FTP, FTPS, HTTP, HTTPS, TFTP, SCP,SFTP, Telnet, DICT, FILE, and LDAP. The main purpose and use for cURL is to automate unattended file transfers or sequences of operations. For example, it is a good tool for simulating a user's actions at a web browser. Under Ubuntu Linux, you can install curl using the following command: apt-get install curl Templates location: The full path of your Default_Template directory. Profile location: The full path to your profile configuration file (usually, it's best to leave this in mod/profile/). Finally, when you're done, click on the Save button to save the settings. Note : The next version of Elgg, Elgg 0.9, will further simplify installation. Already an early release candidate of this version (elgg-0.9rc1) is a lot more straightforward to install and configure, for initial use. First Log In Now, it's time to let Elgg use these settings and set things up for you. Just point your browser to your main Elgg installation (http://<your-web-servergt;/<Elgg-installation>). It'll connect to the MySQL database and create some tables, then upload some basic data, before taking you to the main page. On the main page, you can use the news account and the password you specified for this account during configuration to log in to your Elgg installation.
Read more
  • 0
  • 0
  • 16066
Modal Close icon
Modal Close icon