Friday, July 30, 2010

Groovy magic

All text and example are from:


Implementing the GroovyObject

Groovy's MOP system includes some extension/hooks points that you can use to change how a class or an object behaves, mainly being
  • getProperty/setProperty: control property access
  • invokeMethod: controls method invocation, you can use it to tweak parameters of existing methods or intercept not-yet existing ones
  • methodMissing: the preferred way to intercept non-existing methods
  • propertyMissing: also the preferred way to intercept non-existing properties

invokeMethod()
In any Groovy class you can override invokeMethod which will essentially intercept all method calls. Simple usage of invokeMethod is to provide simple AOP style around advice to existing methods:
class MyClass implements GroovyInterceptable {
  def invokeMethod(String name, args) {
   
      System.out.println ("Beginning $name")
       def metaMethod = metaClass.getMetaMethod(name, args)
      def result = metaMethod.invoke(this, args)
        System.out.println ("Completed $name")
      return result
  }
} 

getProperty()
You can also override property access using the getProperty and setProperty property access hooks.
class Expandable {
  def storage = [:]
  def getProperty(String name) { storage[name] }
  void setProperty(String name, value) { storage[name] = value }
}

def e = new Expandable()
e.foo = "bar"
println e.foo

methodMissing
class Person {
 String name
 String sayHello( toWhom ){ "Hello $toWhom" }
}

Person.metaClass.methodMissing = { String name, args ->
 "$name() called with $args"
}

def duke = new Person(name:'Duke')
assert duke.sayHello('world') == 'Hello world'
assert duke.greet() == 'greet() called with {}'
assert duke.greet('world') == 'greet() called with {"world"}'



ExpandoMetaClass 

Every object in groovy has a MetaClass, responsible for holding information about the object's class. You can obtain list of methods, add your methods and other meta-programming scenarios.


Finding method
println obj.metaClass.methods
println obj.metaClass.methods.find { it.name.startsWith("to") }

class Foo {
 String prop
 def bar() { "bar" }
 def bar(String name) { "bar $name" }
 def add(Integer one, Integer two) { one + two}
}

def f = new Foo()

if(f.metaClass.respondsTo(f, "bar")) {
 // do stuff
}

if(f.metaClass.respondsTo(f, "bar", String)) {
 // do stuff
}

if(!f.metaClass.respondsTo(f, "bar", Integer)) {
 // do stuff
}

if(f.metaClass.respondsTo(f, "add", Integer, Integer)) {
 // do stuff
}
Note method respondsTo


Finding properties
println obj.metaClass.properties
println obj.metaClass.properties.find { it.name.startsWith("to") }

class Foo {
 String prop
 def bar() { "bar" }
 def bar(String name) { "bar $name" }
 def add(Integer one, Integer two) { one + two}
}

def f = new Foo()
if(f.metaClass.hasProperty(f, "prop")) {
// do stuff
}
Note method hasProperty


Add behavour
import org.apache.commons.lang.StringUtils

String.metaClass.capitalize = {
 StringUtils.capitalize(delegate)
}

String.metaClass.normalize = {
 delegate.split("_").collect { word ->
    word.toLowerCase().capitalize()
 }.join("")
}

assert "Groovy" == "groovy".capitalize()
assert "CamelCase" == "CAMEL_CASE".normalize()

Example2
class Person {
 String name
}

Person.metaClass.greet = {
 "Hello, I'm $name"
}
def duke = new Person(name:'Duke')
assert duke.greet() == "Hello, I'm Duke"
Overload method:
Person.metaClass.whatIsThis = { String arg ->
 "it is a String with value '$arg'"
}
Person.metaClass.whatIsThis << { int arg ->
 "it is an int with value $arg"
}

assert duke.whatIsThis( 'Groovy' ) == "it is a String with value 'Groovy'"
assert duke.whatIsThis( 12345 ) == "it is an int with value 12345"

Inheritance is not enabled by default
class Person {
 String name
}
class Employee extends Person {
 int employeeId
}

Person.metaClass.greet = { -> "Hello!" }

def duke = new Person(name:'Duke')
assert duke.greet() == "Hello!"
def worker = new Employee(name:'Drone1')
// the following line causes an exception!!
assert worker.greet() == "Hello!"

Normally when you add a MetaMethod, it is added for all instances of that class. However, for GroovyObjects, you can dynamically add methods to individual instances by giving that instance its own MetaClass.



Categories

With categories you have control over add methods.
  • any public static method is a candidate to be a category method
  • the type of the first parameter is the target type that may have the new methods
  • there is no need to extend a particular class or implement an interface

if you try to call any of those methods outside use() an exception will be thrown.

Saturday, July 24, 2010

DTD

All text are from http://www.w3schools.com/dtd


A Document Type Definition (DTD) defines the legal building blocks of an XML document. It defines the document structure with a list of legal elements and attributes.

A DTD can be declared:
  • inside XML
  • external reference
DTD is not XML document.

DTD inside:
 

DTD external
 


Why is DTD useful

  • With a DTD, each of your XML files can carry a description of its own format.
  • With a DTD, independent groups of people can agree to use a standard DTD for interchanging data.
  • Your application can use a standard DTD to verify that the data you receive from the outside world is valid.
  • You can also use a DTD to verify your own data.

Bulding blocks in XML

  • Elements
  • Attributes
  • Entities
  • PCDATA
  • CDATA
Entities
The following entities are predefined in XML:
Entity ReferencesCharacter
&lt<
&lt<
&amp&
""
''


PCDATA
PCDATA means parsed character data.
PCDATA is text that will be parsed by a parser. The text will be examined by the parser for entities and markup.

CDATA
CDATA means character data.
CDATA is text that will not be parsed by a parser. Tags inside the text will NOT be treated as markup and entities will not be expanded.

Elements

Declaring
<!ELEMENT element-name category>
or
<!ELEMENT element-name (element-content)>

Empty elements
<!ELEMENT br EMPTY>

Elements with PCDATA
<!ELEMENT from (#PCDATA)>

Element with children
<!ELEMENT note (to,from,heading,body)>

When children are declared in a sequence separated by commas, the children must appear in the same sequence in the document. In a full declaration, the children must also be declared, and the children can also have children. The full declaration of the "note" element is:

<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

One occurence
<!ELEMENT note (message)>

One and more
<!ELEMENT note (message+)>

Zero and more
<!ELEMENT note (message*)>

Zero or one
<!ELEMENT note (message?)>

Either/ or content
<!ELEMENT note (to,from,header,(message|body))>

Mixed content
<!ELEMENT note (#PCDATA|to|from|header|message)*>

Attributes

Declaring attributes
<! ATTLIST element-name attribute-name attribute-type default-value>

Example:
<!ATTLIST payment type CDATA "check">

The attribute-type can be one of the following:
TypeDescription
CDATAThe value is character data
(en1|en2|..)The value must be one from an enumerated list
IDThe value is a unique id
IDREFThe value is the id of another element
IDREFSThe value is a list of other ids
NMTOKENThe value is a valid XML name
NMTOKENSThe value is a list of valid XML names
ENTITYThe value is an entity
ENTITIESThe value is a list of entities
NOTATIONThe value is a name of a notation
xml:The value is a predefined xml value


The default-value can be one of the following:
ValueExplanation
valueThe default value of the attribute
#REQUIREDThe attribute is required
#IMPLIEDThe attribute is not required
#FIXED valueThe attribute value is fixed


Default attribute value
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">

In the example above, the "square" element is defined to be an empty element with a "width" attribute of  type CDATA. If no width is specified, it has a default value of 0.

Enumerated values
<!ATTLIST payment type (check|cash) "cash">

Example:
<payment type="check" />
or
<payment type="cash" />

Why is elements better then attributes

Data can be stored in child elements or in attributes.

Attribute:
 

Element:
 

Some of the problems with attributes are:
  • attributes cannot contain multiple values (child elements can)
  • attributes are not easily expandable (for future changes)
  • attributes cannot describe structures (child elements can)
  • attributes are more difficult to manipulate by program code
  • attribute values are not easy to test against a DTD
Use attributes only to provide information that is not relevant to the data.

Example:
 


Entities

Entities are variables used to define shortcuts to standard text or special characters.   
  • Entities can be declared internal or external
Internal
<!ENTITY entity-name "entity-value">

Example
<!ENTITY copyright "Copyright W3Schools.">

External
<!ENTITY entity-name SYSTEM "URI/URL">

Example
<!ENTITY writer SYSTEM "http://www.w3schools.com/entities.dtd">


Wednesday, July 21, 2010

XML in nutshell

All text are from http://www.w3schools.com/xml/


Basic

XML was designed to transport and store data.
XML is use to:
  • XHTML
  • WSDL for describing available web services
  • WAP and WML as markup languages for handheld devices
  • RSS languages for news feeds
  • RDF and OWL for describing resources and ontology
  • SMIL for describing multimedia for the web


Syntax rules:
  • All XML elements must have a closing tag
  • XML are case sensitive
  • XML elements must be properly nested
  • XML document must have a roo element
  • XML attribute values must be quoted


There are 5 predefined entity references in XML:
<<less than
>>greater than
&&ampersand
''apostrophe
""quotation mark




XML elements naming rules:
  • Names can contain letters, numbers, and other characters
  • Names cannot start with a number or punctuation character
  • Names cannot start with the letters xml (or XML, or Xml, etc)
  • Names cannot contain spaces


Validation

XML with correct syntax is "Well Formed" XML.
XML validated against a DTD is "Valid" XML.


DTD (Document Type Definition )
The purpose of a DTD is to define the structure of an XML document. It defines the structure with a list of legal elements:
 


XML Schema
W3C supports an XML-based alternative to DTD, called XML Schema:
 


XML validator
http://validator.w3.org/


XML Namespace

XML Namespaces provide a method to avoid element name conflicts.
Namespaces can be declared in the elements where they are used or in the XML root element:


Note: The namespace URI is not used by the parser to look up information.
The purpose is to give the namespace a unique name. However, often companies use the namespace as a pointer to a web page containing namespace information.

In the XSLT document below, you can see that most of the tags are HTML tags.
The tags that are not HTML tags have the prefix xsl, identified by the namespace xmlns:xsl="http://www.w3.org/1999/XSL/Transform":


CDATA - (Unparsed) Character Data

The term CDATA is used about text data that should not be parsed by the XML parser