Posts mit dem Label oracle adf werden angezeigt. Alle Posts anzeigen
Posts mit dem Label oracle adf werden angezeigt. Alle Posts anzeigen

2017-08-10

Fixing Currency Behaviour in JDeveloper / ADF 12c

As many questions regarding Currency fields in ADF have come to me lately, let me just give you an example of how to tackle these.

It seems, that there is a common error in ADF for German users (or to any other language,where the decimal and grouping delimiter is exactly switched to the English definition).

English (US) Format: $ #,###.##

German Format #.###,##€

As you see, for germans the ',' is changing places wit the '.'

Normally, this would not be much of a deal, but in ADF there seems to be a "hard coded" interpretation somewhere.

So in a simple form, let us type in a salary of 9.999,99 which is a correct entry for the salary field in German.


In case you enter it as the hint provides (that means including the currency symbol) everything seems to work. But for many cases, users are not accustomed to entering the currency symbol.

So let us create our own converter class to fix this issue:

At first, create a java class that is implementing the javax.faces.convert.Converter Interface. This should be annotated by the FacesConverter tag to make it selectable in the UIComponents properties afterwards and removes the requirement to handle the faces-config.xml tracking.


package de.teampb.conv;

import java.math.BigDecimal;

import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;

import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;

import oracle.adf.share.logging.ADFLogger;

/**
 * Custom JSF Faces Converter to convert entries in Currency Input Texts in a correct way. Oracle ADF seems to be a bit
 * confused, if the grouping character in a Locale is '.' and the decimal delimiter is '.' (for example in Germany).
 */
@FacesConverter("de.teampb.conv.CurrencyConverter")
public class CurrencyConverter implements Converter {

    /**
     * Class logger.
     */
    private static final ADFLogger LOG = ADFLogger.createADFLogger(CurrencyConverter.class.getName());

    /**
     * Converter method from UI Entry to data value. Takes an Input String from the UI Component and converts it to a
     * BigDecimal value for data changes.
     *
     * @param facesContext current JSF Context
     * @param uIComponent Component that has a new value
     * @param string Entered String value (may contain groupings, delimiter or currency symbol)
     * @return correctly converted BigDecimal object for the given input
     */
    @Override
    public Object getAsObject(FacesContext facesContext, UIComponent uIComponent, String string) {
        LOG.entering("CurrencyConverter", "getAsObject", new Object[] { uIComponent, string });
        BigDecimal result;

        final Locale locale = facesContext.getViewRoot().getLocale();
        LOG.finest("Locale for Conversion: " + locale.getLanguage());

        if (string != null && !string.isEmpty()) {
            LOG.finest("Parsing numeric sanity of string...");
            Pattern regex = Pattern.compile("[&:;=?@#|]|[a-zA-Z]");
            Matcher matcher = regex.matcher(string);
            if (matcher.find()) {
                NumberFormat f = NumberFormat.getCurrencyInstance(locale);
                throw new ConverterException(f.format(123456.78));
            }
            LOG.finest("...done");

            String res = string;
            DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);

            // get Locale specific grouping and decimal seperators
            char sep = symbols.getDecimalSeparator();
            LOG.finest("Decimal Separator used: " + sep);
            char grp = symbols.getGroupingSeparator();
            LOG.finest("Grouping Separator used: " + grp);

            // remove groupings
            String valueConverted = string.replace(grp, Character.MIN_VALUE);
            LOG.finest("String removed of groups:" + valueConverted);

            // change decimal seperator to "US" standards
            valueConverted = valueConverted.replace(sep, ".".charAt(0));
            LOG.finest("String with changed decimal separator:" + valueConverted);

            // throw away any non numeric stuff
            res = valueConverted.replaceAll("[^\\d.]+", "");

            LOG.finest("Expected result:" + res);
            result = new BigDecimal(res);
        } else {
            LOG.finest("Input was empty, so create a zero object");
            // this is of course project specific, can also return null etc.
            result = new BigDecimal(0);
        }
        LOG.exiting("CurrencyConverter", "getAsObject", result);
        return result;
    }

    /**
     * Converter method to create a correct currency String for a given data object.
     *
     * @param facesContext current JSF Context
     * @param uIComponent UI Component that will get the String value
     * @param object data value that shall be converted
     * @return correct String representation of data to a set Locale
     */
    @Override
    public String getAsString(FacesContext facesContext, UIComponent uIComponent, Object object) {
        LOG.entering("CurrencyConverter", "getAsString", object);

        final Locale locale = facesContext.getViewRoot().getLocale();

        LOG.finest("Locale for Conversion: " + locale.getLanguage());
        NumberFormat f = NumberFormat.getCurrencyInstance(locale);
        String res = f.format(object);

        LOG.exiting("CurrencyConverter", "getAsString", res);
        return res;
    }
}

Hint: As you can see from the source code, the converter uses the Locale's specific grouping and decimal seperators, so this converter should be working for any given locale and currency representation.

Next, add this converter to a converter component inside the UI Field that should use this converter:



That's it, we can now just enter the values in simple fashion.

If we enter the value 9999,99 once again, we will see the estimated behaviour.





This entry shows, how easy it is to create a converter to a RichUIInput component, another nice use case could be, that you enter a value with a currency and then use the converter to calculate the currency exchange rate and thus convert it to the databases default currency.

Feel free to check out an example project from the German ADF Community (a subgroup of the German Enterprise Application Development Group) github:

ADFCommunityDE/ADFCustomCurrencyConverter

Thanks for the read, cheers!

2017-02-28

Delaying Attribute Validations in ADF for LOV-based fields until commit

I think many ADF developers have encountered the unlazy validation of JSF components during their UI implementations. Especially when creating a new record, the auto submit / partial trigger reactions are quite unpleasant for users. Take this for example:


In this, the user inserted the fields in tab-order. After leaving the field salary (doing a auto submit, triggering the job field), the job validator executes and marks a red border to inform the user of the issue. As the user has never inserted the field up to this point, this is not very nice. One valid change is to remove the mandatory flag from the attribute and delegate the validation towards entity level. But then, you will lose the "red border at attribute" response and get a FacesMessage leaving the user in question, which attribute to change to solve the invalid entity.

Andrejus Baranovskis has written a nice article, how to solve this issue when encountering attributes on the same entity, the validation is occuring on:

http://andrejusb.blogspot.de/2017/02/setting-invalid-fields-for-ui-in-adf-bc.html

So let us extend the usecase a bit.

Issue:

For many List of Value components, users do not want to see the key (for example JobId) in the input text, but the looked up value (JobTitle in this case).



To implement this, there are many options to take. To combine the lov requirement and the delayed attribute validation, let me show you one implementation, that works and is quite declarative.

Define the following use cases:

  • Users want to be able to change the Job of an employee using a list of values showing the title, not the id of the job
  • When changing the salary of an employee, the job will be nullified
  • An empty job leads to a validation, but this should only occur on save button or navigation

The second use case defines the usage of partial triggers / auto submit on JSF side later on.

Solution:

To start, we need the base Entity (Employees), a View Object on that entitity (EmployeesView) and a Lookup View Object (JobsLookupView).


Next create a Transient Attribute on Employees Entity, representing the JobName. This will be the target Attribute for the delayed validation and is the base attribute for the lov.

This Attribute uses an expression referring a ViewAccessor on JobsLookupView:




Expression:

JobId != null ? JobsLookupView.getAllRowsInRange().find{it['jobId']==JobId}['jobTitle'] : null

Next, we will add the entity validation (referring Andrejus' blog entry):


(opt. add failure message)

Add dependencies on Entity attributes:




Additionally remove the mandatory flag from the JobId Attribute (to allow entity validation to do the not null check)

Add LOV to EmployeesView JobName Attribute:


(rem: We can use the Employee-level view accessor in this case because we do not use dynamic query components in this example, so no additional view object instances needed).

Create UI

Finally just create a simple Form Layout on a page, removing the JobId Attribute and ensuring the InputListOfValues Component for JobName.




Then update the following attributes for Salary resp. JobName Components:



Additionally, drag the CreateInsert Operation onto the page, to create a new record.

When running the app, and creating a new employee again tabbing through the form, we will see, there is no validation when tabbing out of the salary field (because the showRequired=true instead of mandatory=true).



When commit or navigation is triggered, the entity validation will fire, but because of the special validation attribute, we will see this on the single attribute instead of a FacesMessage.


This is especially helpful, if you are editing data inside a popup.


TL;DR / Result:

Please feel free to checkout a demo application implementing the shown at the german ADFCommunity github repository

https://github.com/ADFCommunityDE/DelayedAttributeValidationOnLookup.git

Any questions regarding this topic or want to see a feature/idea implemented in ADF? Just send me a message ;)

mail:     mke@team-pb.de
twitter:  @MarkusKlenke

Cheers!

2017-02-13

Individual Frame Layout in ADF 12c via custom RichRenderer Class

In one of our Forms to ADF modernization projects, one of our customers wanted to keep the UI structure more or less the same. For many components, there are best practices to map one Oracle Forms UI Component to ADF Structures, but in our case, we had to provide a solution to the following UI-Container Pattern:

<<NamedFramePattern>>
The idea of this pattern is to provide help for the user to see a categorization of UI Items. In general ADF, this might be done via UI Categorization via UI Hints at View Object Level. Unfortunately, this resolves into af:group containers on UI, which are interpreted by the parent container to make sense out of the items. So all in all, we are limited by the frameworks default implementations.

To solve the problem, we thought about the general solution in free html/css context. Here the problem is easy to solve. See

http://jsfiddle.net/ZgEMM/685/

for a sample solution. To reach the explicit HTML code you need out of JSF components is (in most cases) not possible.

Again, ADF supports the creation of own declarative components, but typically we just join other JSF compontents to our liking.

So we have to go one step further. The next steps show you how to create a "component/renderer" mashup to achieve the NamedFramePattern in ADF.

1. Create a declarative container component that has only a panel group layout and a content facetRef. Be sure to add a ComponentClass to your Declarative component for easier access and uniqueness afterwards.







(The Group layout inside is necessary, since all declarative components are not rendered per definition of the UIXBaseComponent-Renderer because it is only a reference for a JSF include).

2. Create a RichRenderer that is based on the renderer for ADF Group Layouts and add additional HTML code to the rendered feature. This can be done by overriding the encodeAll(...) method of the parent class.


package de.teampb.ir.templates.nf;

import java.io.IOException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import javax.faces.context.ResponseWriter;

import oracle.adf.view.rich.component.rich.fragment.RichDeclarativeComponent;
import oracle.adf.view.rich.component.rich.layout.RichPanelFormLayout;
import oracle.adf.view.rich.render.ClientComponent;
import oracle.adf.view.rich.render.RichRenderer;

import oracle.adfinternal.view.faces.renderkit.rich.DeclarativeComponentRenderer;

import org.apache.myfaces.trinidad.bean.FacesBean;
import org.apache.myfaces.trinidad.context.RenderingContext;
import org.apache.myfaces.trinidad.render.CoreRenderer;

import oracle.adfinternal.view.faces.renderkit.rich.PanelGroupLayoutRenderer;

public class NamedFrameRenderer extends PanelGroupLayoutRenderer {
    public NamedFrameRenderer() {
        super();
    }

    private static final String DEFAULT_COLOR = "#AAAAAA";

    private static final String IMPORTANT_COLOR = "#FFAAAA";

    @Override
    protected void encodeAll(FacesContext facesContext, RenderingContext renderingContext, UIComponent uIComponent,
                             ClientComponent clientComponent, FacesBean facesBean) throws IOException {
        ResponseWriter rw = facesContext.getResponseWriter();
        if (uIComponent.getParent() instanceof NamedFrame) {
            NamedFrame nf = (NamedFrame) uIComponent.getParent();
            rw.startElement("div", null);
            rw.writeAttribute("style", "border: 2px solid " + getColor(nf) + "; margin: 5px; padding: 5px", null);
            rw.startElement("h2", null);
            rw.writeAttribute("style",
                              "text-indent: 30px;\n" + "    margin-top: -10px;\n" + "    height: 10px;\n" +
                              "    line-height: 20px;\n" + "    font-size: 15px;", null);
            rw.startElement("span", null);
            rw.writeAttribute("style", "background-color:#FFFFFF; color:#000000;", null);
            rw.writeText(nf.getTitle(), null);
            rw.endElement("span");
            rw.endElement("h2");
            super.encodeAll(facesContext, renderingContext, uIComponent, clientComponent, facesBean);
            rw.endElement("div");
        } else
            super.encodeAll(facesContext, renderingContext, uIComponent, clientComponent, facesBean);
    }

    private String getColor(NamedFrame nf) {
        if ("important".equals(nf.getType())) {
            return IMPORTANT_COLOR;
        } else
            return DEFAULT_COLOR;
    }

}

The idea is that the renderer overrides the default Renderer for Panel Group layouts. So we have to keep the default implementation (the inside super.encodeAll line).

(The HTML code could be beautified by using classes instead of inline style, but I think you get the idea)

3. Add renderer to faces-Config.xml in the consuming ViewController Project.


4. Use declarative component as usual to achieve the layout addition by the renderer.






As you can see from the last image, since the JDeveloper design view uses the internal renderer classes we also get the advantage of what-you-see-is-what-you-get development. The resulting ADF application then looks as follows:




Please feel free to download the sources at

https://github.com/TEAMPB/ADF_POC.git

and pull the sources. To run the application, you need access to an HR schema. Then Run the hr-main.xml Task-Flow.

Cheers!

2016-04-29

Handling very slow execution of CreateInsert in JDeveloper 12.2.1

Many of you might encounter a serious performance issue with the createInsert functionality of ADF in 12.2.1. In detail:

If you have a large result set after a query (ex. a master data dialog) and you want to create a new record, the framework executes the findByKey method as many as four times  as there are records in the result set of the query (check Andrejus Baranovski's blog entry: Evil behind the ChangeEventPolicy PPR). This only happens, if you did not fetch all data up to the point of inserting a new row (so having -1 as range size will fix this, although querying many thousands of rows to create one seems not to be a good idea ;) ).

As we faced the same issue for a customer project, we tried to find out, what exactly is the issue here.

Preparation:

In our test we have the following conditions - A Table containing  ~ 70000 entries with randomly generated Char content in each column. For this, we created the default BC, so an Entity Object with the default settings, a corresponding default View Object and an Application Module.

On View Controller side, we have just a plain page with an af:table created by drag and drop from data controls. On the table, we set the following properties:

contentDelivery="immediate"
autoHeightRows="10"
rangeSize=13 -> leads to property change of iterator in page definition

For completion of the preparation, we add the navigation and crud buttons to the ui.



When running the page and clicking on CreateInsert, we see, that this takes a long time (it can get significantly worse for real data).



On a second run (make sure a new session is built up), click last first and then the create insert. This takes some time for the last-button click, but the insert afterwards is done immediately. So what happens?

Problem description:

The newest version of ADF has some changes in the Key mechanism. The most important (in general but also in our case) is that a key of a newly created  row is not null itself, but a Key Object containing null values, which seems like a good idea in most cases.

This change has a serious impact on the retrieveByKey in the ViewObject method, which seems to check if(key == null), which is never true in the new Version (since we always have a Key object at hand).

In case the data is not already fully fetched from the database, ADF creates a new RecordSet for the find by key method (which makes sense in case you are searching for a row that might not be already in the fetched Rows). In general this new View Object uses the constraints of the original View Object, but in most cases for master data dialogs, there are no real constraints in the first place.

In case of the insert, a findByKey is executed (coming from the af:table, which is refreshed by ppr; again, see the post of Andrejus), coming with a key that is not null, but contains only null values. Since the fetch size is obviously not reached (we have 13 rows out of 70000), a new View Object is created in background and executed for the findByKey, which never will be finding any Row. Strangely, this seems to be executed for each row that is in the range and before the currently inserted row. So in worst case, the query would be executed up to 12 times in the example.




Solution:

Personally, I think, Oracle must take a look at this and maybe change some implementations at this part. But as we know, it might take a while until fixing the issue. So here is a workaround. In your ViewObjectImpl (better, a base ViewObjectImpl that is superclass of all your View Objects) override the following method:

   @Override
   protected Row[] retrieveByKey(ViewRowSetImpl rs, String keyName, Key key, int  maxNumOfRows, boolean skipWhere) {
        if (!key.isNull() || keyName != null) {
            return super.retrieveByKey(rs, keyName, key, maxNumOfRows,    skipWhere);
        }
        return new Row[0];
    }

 
This is just a safety fallback, that if all of the key columns are null the findByKey mechanism is not executed at all. In all other cases (i.e. you really want to search a row by its key or part of its key), the framework default will do its job.

In the Example, we created the same UI with a View Object that has the fix (FixedRandomEntriesView). In this case, the create is done immediately, even if the fetch does not have all rows, wich solves our problem.

One should state, that this solution is only applicable for blank inserts (i.e. no DBSequences etc.). In this case, you have to put some further effort to the overriden method to check if you are in insert mode or search mode.



You can download the sample app here: CreateInsert12211 Example
To work with our example data, you can use this sql script to create the table and insert data: Random_Entries.sql

2016-03-21

SelectOneChoice im JDeveloper 12.2.1

Im JDeveloper 12.2.1 hat sich ein Stylingingfehler bei der Komponente SelectOneChoice eingeschlichen.
In einem Formular rutschen die Inhalte nach oben, sowohl im Read-Only als auch im Auswahl-Fall. Im Rahmen einer Tabelle fällt das Verhalten nicht auf, da dort der Inhalt zentriert wird.
Hier die Beispiele (Felder JobId, ManagerId und BepartmentId):




Um den Fehler zu korrigieren müssen wir den Skin anpassen.
Dazu erstellen wir einen Skin:

Im ViewControler-Projekt New > From Gallery wählen


 "ADF Skin" wählen:


 Wir wählen einen schönen Namen:

und wechseln in den Source-View des Skins und fügen wir folgende Zeilen hinzu:

af|selectOneChoice .AFPanelFormLayoutContentCell  {
    padding-top : 8px;
}

af|selectOneChoice af|panelFormLayout::label-cell {
    padding-top: 8px;

}

und erhalten:


Damit die Anzeige klappt, einmal die Applikation undeployen und neu starten und schon erhalten wir:




2015-11-12

DOAG 2015 Konferenz + Ausstellung, selbstverständlich nicht ohne TEAM

Auch in diesem Jahr ist TEAM auf der DOAG 2015 Konferenz + Ausstellung selbstverständlich mit einem Messestand und gleich mit fünf Vorträgen vertreten. Besuchen Sie uns und lernen Sie das umfassende Consulting-Angebot von TEAM kennen. Es gibt jede Menge aktuelle Themenschwerpunkte, über die wir uns gerne mit Ihnen an unserem Stand 204 in der 2. Etage (gelb) unterhalten möchten!
Oder besuchen Sie TEAM bei folgenden, spannenden Vorträgen zu den Streams
  • Strategie & Business Practices
  • Development
  • Middleware
  • Oracle Datenbank
einen Querschnitt der Themenfelder aus unserem "Oracle Business" repräsentieren:
Ein Lizenzaudit: Besorgniserregend oder entspannt angehen?
Dienstag, 17. November 2015, um 11:00 Uhr im Raum Stockholm
Referent: Ralf Appelbaum, TEAM GmbH
Detail-Informationen finden Sie hier.
Effiziente Modernisierung von Oracle-Anwendungen auf Alta UI
Dienstag, 17. November 2015, um 16:00 Uhr im Raum Hongkong
Referenten: Janis Krasemann, enpit consulting OHG; Markus Klenke, TEAM GmbH
Detail Informationen finden Sie hier.
Tuning Oracle Web-Applications in WLS 12c
Mittwoch, 18. November 2015, um 11:00 Uhr im Raum Prag
Referent: Markus Klenke, TEAM GmbH
Detail Informationen finden Sie hier.
Oracle Backup & Recovery - Konzepte, Umsetzung, Best Practice
Mittwoch, 18. November 2015, um 12:00 Uhr im Raum St. Petersburg
Referent: Andreas Kother, TEAM GmbH
Detail Informationen finden Sie hier.
Einfach erklärt: RAC Grundlagen für Dummies
Donnerstag, 19. November 2015, um 09:00 Uhr im Raum Seoul
Referent: Ralf Appelbaum, TEAM GmbH
Detail-Informationen finden Sie hier.

2015-06-16

Disable Browser Navigation Buttons for ADF 12c Web Applications

Recently, we got a request that a customer wanted the browser navigation buttons disabled on his ADF 12c application. As we know, it is not possible to disable the buttons of the browser by default (unless you want to build your own private browser ;)). So we had to find another solution.

Hence ADF 12c comes with great HTML5 support, we found the solution in the javascript HTML5 history API. With it, it is possible to recreate the last entry of the browser history stack. The idea is fairly simple:

Browser pops the top stack element with the popstate event; we push the same element on top again, so that the user stays on the same page. Even the code is very short and easy to implement:

1. Create a <af:resource type="javascript"> tag on your page and add the following content:



function onPageEntry(){            

               //push the initial state first, to keep the current state named and referencable
                history.pushState(null, null, 'name-of-your-page');

               //if popstate is fired, add the push to the event queue
                window.addEventListener('popstate', function(event) {
                history.pushState(null, null, 'name-of-your-page');
                });
              }



2. create a client listener at document-on-load level, that references the javascript function:

<af:document title="PageTitle" id="d1">
   <... many more tags>
   <af:clientListener method="onPageEntry" type="load"/>
</af:document>

That's it. One might say, that this is a very crude way to "disable" the functionality, but as it is still possible to rightclick the buttons and navigate back to your older history, I think this is a nice safety-approach for ADF applications, that does not affect the browser in general.

2014-07-02

Forms2ADF mal anders: Wie aus einer Oracle-Vision Praxis wird

Sollte der Film im letzten Post noch nicht detailliert genug beschrieben haben, wie eine Modernisierung von Forms zu ADF bei TEAM aussieht, so kann der Artikel

Forms2ADF mal anders: Wie aus einer Oracle-Vision Praxis wird


aus der aktuellen DOAG News weiterhelfen.

Dort beschreibt TEAM wie genau eine Modernisierung modellgetrieben durchgeführt werden sollte, um ein qualitativ hochwertiges und erweiterbares Ergebnis zu erzielen.

2014-05-02

TEAM - Wir migrieren anders



So macht eine Forms-Anwendung wieder Spaß

2014-04-30

Forms Migration Services - The clever way of Forms modernization


After several years of intensive research in cooperation with s-lab, a special interest group of the University of Paderborn supporting industrial partners in developing new technologies, TEAM proudly presents the Forms Migration Services – a process to take your Forms application to the next level using a model driven migration approach containing the TEAM Migration Assistant - a toolset for semi-automatic modernizations. Do the results justify all the effort? Yes, definitively!

In accordance with the objective to transform a Forms application into a maintainable ADF application, the project team initially followed the approach of a fully automated migration. This initial idea had to be revised, however, due to the technical differences between the two platforms Forms and ADF. A wider approach had to be taken in order to achieve appropriate/satisfactory results. Migrating a Forms application using a single blue print which transforms dialogue by dialogue and even generates a "Forms-Runtime" in ADF may represent a viable method to generate a running ADF application; however, this application would neither be maintainable nor would it offer any extension points to allow progression of the application. Thus it was obvious that a more sophisticated and abstract way of thinking was needed to solve the issues a 1:1 migration brings along.

Keeping that in mind, the project team, consisting of TEAM developers and s-lab members, developed a new approach to transforming and, at the same time, modernizing a Forms application into a “true” ADF application. A major challenge in this process was the fact that most Forms applications have been developed with a company specific Forms framework (i.e. functions and objects extending the original Oracle Forms framework). The new migration method is based on a multilevel modernization process. By using tools for source code analysis, knowledge and patterns for the specific Forms application are recognized and transformation rules can be established. These rules provide project specific patterns to the TEAM Migration Assistent which then generates the ADF application iteratively. Each iterative step is to be finished manually. After each step, our migration experts and the development team come together to discuss the lessons learned and whether or not recent development steps or code fragments can be automated in the next iteration step. This procedure ensures that the following iteration steps can be finished a lot quicker.



The Forms Migration Services offered by TEAM provide a novel integrated concept to modernize your Oracle Forms application to a "true" ADF application that is maintainable, great looking and enabled for future implementations!

2014-02-07

Forms - Quo Vadis

Mit Oracle Forms werden seit Jahrzehnten Datenbankanwendungen entwickelt. Oracle hat versucht, Forms immer wieder an den Stand der Technik anzupassen.

Doch spätestens seit dem "Statement of Direction" im März 2012 hat Oracle klar aufgezeigt, dass neue Technologien nicht mehr mit Forms realisiert werden können. Stattdessen hat Oracle das Application Development Framework (ADF) entwickelt, um den neuen technologischen Aufgaben gewachsen zu sein. Wenn Oracle-basierte Applikationen webfähig gemacht, erweitert, integriert oder ersetzt werden sollen, führt heute kein zukunftsorientierter Weg an Oracle ADF vorbei.

Sie fragen sich, ob es sinnvoll ist, Ihre Forms Applikation nach ADF zu migrieren oder welcher Weg der Migration der richtige ist? Lassen Sie sich am 18. März 2014 durch diese kostenlose Veranstaltung auf den neuesten Stand bringen!

Speziell ausgebildete und projekterfahrene TEAM-Mitarbeiter zeigen Ihnen, unter anderem anhand einer Live-Demo, ob und wie eine Migration von Forms zu ADF sinnvoll durchgeführt werden kann.
Erfahren Sie alles Wissenswerte zu den Themen Migrationsstrategien, Projektvorgehen und welchen Mehrwert Sie durch eine Migration von Forms zu ADF erhalten können.



Agenda:
13:00
Registrierung und gemeinsamer Imbiss
13:45
Begrüßung und Vorstellung TEAM
Harry Jules Mayo, TEAM GmbH
14:00
Aufbruch in eine neue Welt: Warum Oracle den Wechsel von Forms zu ADF vollzogen hat
Jürgen Menge, ORACLE Deutschland B.V. & Co. KG
14:30
Wenn eine "Migration nach Kochrezept" keinen Sinn macht
Marvin Grieger, s-lab, Universität Paderborn
15:00
Kaffeepause
15:15
Von Forms zur erweiterbaren ADF-Anwendung: Der TEAM Migration Assistant
Markus Klenke, TEAM GmbH
16:15
Mit der neuen ADF Applikation in die Zukunft: Die TEAM ADF-Tools
Christian Kunzmann, TEAM GmbH
16:35
Migration im Projekt: Von der Analyse bis zur ADF-Anwendung
Wolf G. Beckmann und Harry Jules Mayo, TEAM GmbH
17:00
Ende der Veranstaltung


Haben wir Ihr Interesse geweckt? Dann laden Sie hier den Einladungsflyer zur Veranstaltung "Forms Quo Vadis" inklusive Anmeldeformular herunter.