Sep 17, 2007

Τακτοποιώντας κώδικα HTML και XML με τη βοήθεια του tidy

Δεν είναι λίγες οι φορές που θέλοντας να πάρουμε ιδέες και κώδικα από HTML σελίδες, ανατρέχουμε στη λειτουργία "View Page Source" του browser μας. Και εκεί, είναι δυνατόν να βρεθούμε αντιμέτωποι με τακτοποιημένο κώδικα αλλά επίσης υπάρχει η μεγάλη πιθανότητα η σελίδα να έχει παραχθεί με τρόπο αυτόματο ώστε να γίνεται εντελώς αδύνατη η ανάγνωσή της. Ένα τέτοιο παράδειγμα αποτελούν οι σελίδες που παράγονται από το ADF, όπου όλος ο κώδικας τυπώνεται σε μια γραμμή.


Ένα εργαλείο που τακτοποιεί κώδικα HTML και XML, διορθώνει ατέλειες τους και επισημαίνει συντακτικά λάθη τους, είναι το tidy (http://tidy.sourceforge.net/) διαθέσιμο τόσο σε Linux, Windows αλλά και σε διάφορα λειτουργικά συστήματα. Το tidy προσφέρει ισχυρές δυνατότητες παραμετροποίησης που είναι δυνατόν να αποθηκευτούν σε αρχεία διαμόρφωσης (configuration files) Για παράδειγμα το αρχείο που χρησιμοποιώ περιέχει τις ρυθμίσεις:

quiet: yes char-encoding: utf8 output-file: tidy_output.html indent: true

ώστε να διαβάζει αρχεία σε UTF8, να μην εμφανίζει μηνύματα λαθών, να δομεί ιεραρχικά το κείμενο (ώστε να είναι εύκολο για ανάγνωση) και τέλος να αποθηκεύει τις αλλαγές σε ένα άλλο αρχείο. Παράδειγμα της χρήσης του tidy για το παράδειγμά μας:

tidy -config tidy.cfg CustomersTable.jspx


που είχε σαν αποτέλεσμα ένα αναγνώσιμο HTML αρχείο.

Sep 16, 2007

Ενδιαφέρουσες απόψεις για το λογισμικό

Σε γενικές γραμμές δεν θα ήθελα να προτείνω από αυτό το blog, άλλα blogs ή sites καθότι όλα αυτά αποτελούν ιδιωτική προτίμηση. Υπάρχουν όμως πάντοτε και οι φωτεινές εξαιρέσεις, όπως το wiki του Βασίλη Κούτσικου (http://vassikou.gr) που φιλοξενεί πολύ ενδιαφέρουσες απόψεις για το λογισμικό και τα δρώμενα του χώρου της Πληροφορικής. Τα πιο πρόσφατα άρθρα διαπραγματεύονται με τις περιπτώσεις των Ανεξάρτητων Εθνικών Αρχών αλλά και με τους παράλληλους και συνάμα αντικρουόμενους δρόμους του εμπορικού και του ανοικτού λογισμικού. Περιμένουμε με ανυπομονησία και άλλες δημοσιεύσεις από τον Βασίλη.

Sep 12, 2007

Έλεγχοι (validations) κατά την εκτέλεση ενός wizard στο JHeadstart

Μια από τις πιο ισχυρές ευκολίες που παρέχει το JHeadstart για την ανάπτυξη εφαρμογών ADF, είναι η εύκολη δημιουργία σελίδων για την ολοκλήρωση μιας σύνθετης συναλλαγής που αποτελείται από διάφορα βήματα, που διαμοιράζονται σε πολλαπλές σελίδες. Ο χρήστης ειδοποιείται στο πάνω μέρος της σελίδας για το στάδιο στο οποίο βρίσκεται σχετικά με την περάτωση της συνολικής διαδικασίας. Το ADF Faces component που χρησιμοποιείται ονομάζεται processTrain.

Ένα από τα ιδιαίτερα χαρακτηριστικά του wizard που δημιουργείται είναι πως οι validations κανόνες που έχουν οριστεί σε επίπεδο Entities, δεν ενεργοποιούνται παρά μόνο στο τελευταίο βήμα της όλης διαδικασίας. Παρόλα αυτά, είναι συχνά επιθυμητό, να πραγματοποιούνται οι έλεγχοι κατά την μετάβαση από το ένα βήμα στο επόμενο του wizard, να παρουσιάζονται εκείνη τη στιγμή τα μηνύματα λάθους και να παραμένει ο χρήστης στην ίδια οθόνη για να διορθώσει τις παρατηρήσεις.

Για να επιτευχθεί αυτό, είναι απαραίτητη η επέμβαση στον τρόπο που διαχειρίζεται το JHeadstart το wizard. Αρχικά, ανατρέχουμε στο faces-config αρχείο που κρατά τις ρυθμίσεις των beans για το wizard μας. Από αυτό το αρχείο δανειζόμαστε την κλάση του JHeadstart που διαχειρίζεται τα βήματα του wizard.

Έπειτα, δημιουργούμε μια νέα, δικιά μας κλάση, που κληρονομεί από αυτή του wizard του JHeadstart που βρήκαμε μόλις παραπάνω. Η μοναδική μέθοδος που χρειάζεται να κάνουμε override είναι η getNextAction() που μπορεί να έχει την ακόλουθη δομή:

public String getNextAction() {
// Check of an attribute, of those an end-user has to submit in the first
// page of the wizard.
String value =
(String)JsfUtils.getExpressionValue("#{bindings.MasterDetailWizardGroupOrderId.inputValue}");
// If the user has submitted value.
if (value != null && value.equals("111")) {
// Validate the user input, by invoking the appropriate method
// probably of the Application Module.

// In case of error, stay in the current page.
JsfUtils.getInstance().addError("Value 111 is not allowed !");
return null;
}
checkFocusRowIndex();
return super.getNextAction();
}


Όπως διαφαίνεται, αρκεί να επιλέξουμε ένα attribute το οποίο ξέρουμε πως θα έχει τιμή (π.χ. ύστερα από την αναγκαστική συμπλήρωση του στο κάποιο βήμα του wizard) και με βάση αυτό να εκτελέσουμε το validation κώδικα μας (π.χ. καλώντας μια μέθοδο στο Application Module) Εάν το αποτέλεσμα δεν είναι θετικό, παραμένουμε στην ίδια σελίδα (return null) διαφορετικά καλούμε τη συμπεριφορά που θα έπρεπε να έχει το framework (checkFocusRowIndex(); return super.getNextAction();)

Το τελευταίο κομμάτι που μας απομένει, είναι να ξαναγυρίσουμε στο faces-config των beans μας και να ορίσουμε σαν κλάση του wizard, τη δικιά μας.

Χωρίς καμία άλλη αλλαγή, και χωρίς JHeadstart generation μπορούμε να ελέγξουμε τη συμπεριφορά του συστήματος. Για παράδειγμα έχω ορίσει σαν validation κανόνα πως όταν η συμπλήρωση σε ένα πεδίο είναι η τιμή "111" να εμφανίζεται μήνυμα λάθους, διαφορετικά συνεχίζουμε στο επόμενο βήμα.

Για να οριστικοποιήσουμε τις αλλαγές μας, θα πρέπει να τροποποιήσουμε το κατάλληλο vm αρχείο του Group μας για να περίεχει από εδώ και στο εξής της δηλώσεις στο faces-config bean αρχείο μας.

Sep 2, 2007

Μηχανισμοί ασφάλειας (security) στα ADF Business Components

Είναι εξαιρετικά ενδιαφέρον να παρατηρήσουμε πως τα ADF Business components, πέρα από το O-R mapping και τη θέσπιση επιχειρηματικών κανόνων (validation logic) μπορούν να χρησιμοποιηθούν για τη δόμηση πλαισίου ασφάλειας, διασυνδεδεμένο με το πρότυπο JAAS, σε επίπεδο entity, ακόμα και σε επίπεδο πεδίου. Εξ ορισμού, o JDeveloper εκμεταλλεύεται ένα εσωτερικό αρχείο για ρόλους σε εφαρμογές J2EE. Αντικείμενο αυτού του άρθρου είναι η κατάδειξη πως μπορούμε να δημιουργήσουμε το δικό μας και να το αξιοποιήσουμε στο περιβάλλον μας.

Ξεκινώντας με το JAAS, θα πρέπει να ορίσουμε τους λογικούς ρόλους της εφαρμογής. Γι' αυτό το λόγο, το project μας θα πρέπει να περιλαμβάνει το jazn-data.xml που περιγράφει ακριβώς τους ρόλους που μας ενδιαφέρουν και χρησιμεύει σαν security repository στο καιρό της ανάπτυξης (που φυσικά σε περιβάλλον παραγωγής θα χρησιμοποιηθεί ένα LDAP ή μια βάση δεδομένων). Για να δημιουργηθεί αυτό το αρχείο, επιλέγουμε το ADF BC project μας και διαλέγουμε από το μενού Deployment Descriptors--> OC4J Deployment Descriptor Wizard.

και στο επόμενο βήμα, διαλέγουμε το jazn-data.xml, και την έκδοση που θα υλοποιεί, ανάλογα με το περιβάλλον deployment.

Για να επεξεργαστούμε το αρχείο, επιλέγουμε το jazn-data.xml και οδηγούμαστε στο Properties.

Σε αυτό το σημείο, θα πρέπει να ορίσουμε ένα realm (κάτι σαν το namespace που θα περιλαμβάνει τους χρήστες του οργανισμού, π.χ. mycompany.com), τους χρήστες, τους ρόλους και την αντιστοίχιση μεταξύ τους.

Επαναλαμβάνουμε τη διαδικασία δημιουργίας ενός νέου deployment descriptor, διαλέγοντας αυτή τη φορά τη δημιουργία του αρχείου orion-application.xml

Επεξεργαζόμαστε το αρχείο που μόλις προέκυψε, διαμορφώνοντας την γραμμή:


όπου ορίζουμε δηλαδή το default-realm μας. Σε αυτό το σημείο, θα πρέπει να κλείσουμε τον JDeveloper και να επεξεργαστούμε το αρχείο $JDEV_HOME/j2ee/home/config/jazn.xml. Πιο συγκεκριμένα, χρειάζεται να αλλάξουμε τη γραμμή που ορίζει τη διαδρομή του default jazn-data.xml αρχείου, που οριοθετεί τους εξ ορισμού ρόλους στον JDeveloper, στο αρχείο που φτιάξαμε στο project μας δηλαδή, αλλάζουμε το:

location="./system-jazn-data.xml"


για παράδειγμα σε:
location="/home/spk/Projects/workdir/ADF-Training/OE-Model2/src/META-INF/jazn-data.xml"

Προσοχή: Αυτή η αλλαγή αφορά όλα τα project μας στον JDeveloper, που από εδώ και στο εξής θα βλέπουν αυτούς τους ρόλους. Ξεκινούμε το JDeveloper, προχωρούμε σε ένα entity και στο βήμα Authorization, βλέπουμε τους ρόλους που έχουμε κατασκευάσει και ορίζουμε για παράδειγμα έναν κανόνα read-only πρόσβασης σε ένα συγκεκριμένο πεδίο.

Για τη δοκιμή των παρεμβάσεών μας, διαλέγουμε το Application Module μας και αλλάζουμε την τιμή της παραμέτρου "jbo.security.enforce" σε "Auth" για την ενεργοποίηση του μηχανισμού ασφάλειας και την αυτόματη δημιουργία ενός login παραθύρου.

Ξεκινούμε τον ADF Business Components Tester και βρισκόμαστε αντιμέτωποι με την οθόνη της αυθεντικοποίησης:

Βλέποντας τις εγγραφές του entity που μας ενδιαφέρει, διαπιστώνουμε πως μπορούμε μόνο να προβάλλουμε και όχι να μεταβάλλουμε το πεδίο OrderStatus, οπότε ο κανόνας μας έχει εφαρμοστεί με επιτυχία.