Headline

Exercise in-memory XML processing with Technology:XOM in Language:Java

Characteristics

See Contribution:dom for a general motivation for exercising in-memory XML processing. The present implementation simply exercises yet another DOM-like API. We end up providing a descendants axis to this end.

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd).

Feature:Open serialization is implemented using Technology:xom Builder:

    public static Element deserializeCompany(String file) throws ValidityException, ParsingException, IOException {
        return (new Builder().build(new File(file)).getRootElement());
    }

Feature:Total and Feature:Cut are implemented by using descendants:

	public static double total(Element elem) {
		double total = 0;
		for (Element s : descendants(elem, "salary"))
			total += Double.valueOf(s.getValue());
		return total;
	}

	public static void cut(Element elem) {
		for (Element s : descendants(elem, "salary")) {
			double value = Double.valueOf(s.getValue());
			value /= 2;
			s.removeChildren();
			s.appendChild(new Text(Double.toString(value)));
		}
	}

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
    • org.softlang.company.features for implementations of Functional requirements.
      • org.softlang.company.features.xom for descendants helper.
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Language:

Java

Headline

An OO programming language

Illustration

Let's show "Hello World" for Java.

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello, World");
    }

}

Headline

In-memory XML processing in Language:Java with Technology:DOM

Characteristics

Companies are represented in Language:XML and the object model of Technology:DOM is used to represent and process XML documents in memory. In particular, operations on companies are implemented in Java on top of DOM objects. Such objects are easily queried - as needed for Feature:Total. As DOM objects also mutable, Feature:Cut is implemented as an impure function.

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd).

Feature:Open serialization is implemented by loading and storing a Technology:DOM Document object:

	/**
	 * Parse a file and return the Document object
	 */
	public static Document loadDocument(String filename) {
		try {
			// Create a builder factory
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();

			// Create the builder
			DocumentBuilder builder = factory.newDocumentBuilder();

			// Deserialization by parsing
			Document doc = builder.parse(new File(filename));

			// Done
			return doc;

		} catch (SAXException e) {
		} catch (ParserConfigurationException e) {
		} catch (IOException e) {
		}
		// Return null for any sort of problem
		return null;
	}
	/**
	 * Save a document to a file.
	 */
	public static boolean saveDocument(Document doc, String filename) {

		try {
			// Prepare the DOM document for writing
			Source source = new DOMSource(doc);

			// Prepare the output file
			File file = new File(filename);
			Result result = new StreamResult(file);

			// Creater a transformer factory
			TransformerFactory xfactory = TransformerFactory.newInstance();

			// Create a transformer
			Transformer transformer = xfactory.newTransformer();

			// Force pretty printing
			transformer.setOutputProperty(OutputKeys.METHOD, "xml");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
			transformer.setOutputProperty(
					"{http://xml.apache.org/xslt}indent-amount", "2");
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

			// Serialization by transformation
			transformer.transform(source, result);

			// Done
			return true;

		} catch (TransformerConfigurationException e) {
		} catch (TransformerException e) {
		}
		// Return false for any sort of problem
		return false;
	}

A method to validate the deserialized xml with the Company XSD schema is implemented by a DOM Validator:

	/**
	 * return true if document is a valid company
	 * 
	 */
	public static boolean isValidXml(String xmlFile, String xsdFile) {
		Schema schema = null;
		// Create a builder factory
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

		factory.setNamespaceAware(true);

		// Create a factory for validation
		String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
		SchemaFactory schemaFactory = SchemaFactory.newInstance(language);

		try {
			// Create schema from xsd file
			schema = schemaFactory.newSchema(new File(xsdFile));
			// Create validator
			Validator validator = schema.newValidator();
			// Create DocumentBuilder
			DocumentBuilder builder = factory.newDocumentBuilder();
			// Create document from xml file
			Document doc = builder.parse(new File(xmlFile));
			// validate xml file with xsd schema
			validator.validate(new DOMSource(doc));
			return true;
		} catch (SAXException e) {
			System.err.println(e);
		} catch (IOException e) {
			System.err.println(e);
		} catch (ParserConfigurationException e) {
			System.err.println(e);
		}
		return false;
	}

Feature:Total and Feature:Cut are implemented using methods of Technology:DOM's Document class:

    public static double total(Document doc) {
        // The aggregation variable 
        double total = 0;

        // Get the matching elements
        NodeList nodelist = doc.getElementsByTagName("salary");

        // Process the elements in the nodelist
        for (int i=0; i<nodelist.getLength(); i++) {
            // Get element
            Element elem = (Element)nodelist.item(i);
            total += Double.parseDouble(elem.getTextContent());
        }
        return total;
    }
    public static void cut(Document doc) {
        // Get the matching elements
        NodeList nodelist = doc.getElementsByTagName("salary");

        // Process the elements in the nodelist
        for (int i=0; i<nodelist.getLength(); i++) {

            // Get element
            Element elem = (Element)nodelist.item(i);

            // Transform content of element
            double value = parseDouble(elem.getTextContent());
            elem.setTextContent(Double.toString(value / 2));
        }
    }

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Headline

XML processing with Java's JDOM API

Characteristics

See Contribution:dom for a general motivation for exercising in-memory XML processing. The present implementation simply exercises yet another DOM-like API.

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd).

Feature:Parsing is implemented by loading a Technology:JDOM Document object:

    public static Document parseCompany(String file) throws IOException, JDOMException {
        return new SAXBuilder().build(new File(file));
    }

Feature:Total and Feature:Cut are implemented using methods of Technology:JDOM's Document class:

    public static double total(Document doc) {

        // Aggregate salaries
        double total = 0;

        // Iterate over all salary elements
        Iterator<?> iterator = doc.getDescendants(new ElementFilter("salary"));
        while (iterator.hasNext()) {
            Element elem = (Element)iterator.next();
            Double salary = Double.valueOf(elem.getText());
            total += salary;
        }

        return total;
    }
    public static void cut(Document doc) {

        // Iterate over all salary elements
        Iterator<?> iterator = doc.getDescendants(new ElementFilter("salary"));

        // Snapshot these elements before modification
        List<Element> elems = new LinkedList<Element>();
        while (iterator.hasNext())
            elems.add((Element)iterator.next());

        // Iterate over salary elements and cut salaries
        for (Element elem : elems) {
            Double salary = Double.valueOf(elem.getText());
            elem.setText(Double.toString(salary/2));
        }
    }

Test cases are implemented for all Namespace:Features.

Relationships

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Concept:

In-memory XML processing


Headline

Push-based XML parsing in Language:Java with Technology:SAX

Characteristics

XML processing

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd).

Feature:Parsing is implemented by loading a Technology:sax XMLreader:

    // here a handler can realise unparsing (see Cut)
    public static void parse(DefaultHandler handler, String file) throws SAXException, IOException {
        XMLReader xreader = XMLReaderFactory.createXMLReader();
        xreader.setContentHandler(handler);
        xreader.setErrorHandler(handler);
        FileReader reader = new FileReader(file);
        xreader.parse(new InputSource(reader));
    }

Feature:Unparsing can be implemented by a handler (see Cut).

Feature:Total is implemented by a SAX handler that totals during a parse:

    /**
     * Return the final result of query for totaling salaries.
     */
    public double getTotal() { 
        return total; 
    }

Feature:Cut is implemented by a SAX handler that outputs an XML-file with XMLStreamWriter.

The schema is not needed for the basic operations, but one can perform XML validation with regard to the schema (see package org.softlang.company.features.sax)

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Contribution:

jaxbExtension

Headline

Object-XML mapping for Language:Java and Language:XSD with Technology:JAXB

Characteristics

See Contribution:jaxbComposition for the overall motivation of exercising Technology:JAXB and for arguably a simple baseline of a schema and corresponding schema-derived classes. The present implementation represents an attempt to model different kinds of subunits of department (i.e., sub-departments and employees) as subtypes of a common supertype of subunits, where subtyping is meant here in the sense of XSD's type extension mechanism. The result is rather complex at both ends.

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd). For example departments:

<xs:complexType name="department">
 <xs:complexContent>
  <xs:extension base="subunit">
   <xs:sequence>
    <xs:element ref="name"/>
    <xs:element name="manager" type="employee"/>
    <xs:element maxOccurs="unbounded" minOccurs="0" name="subunit" type="subunit"/>
   </xs:sequence>
  </xs:extension>
 </xs:complexcontent>
</xs:complextype>

Actual Language:Java classes will be generated using Technology:xjc.

Feature:Open serialization is implemented using Technology:JAXB Un-/Marshaller:

    public static Company deserializeCompany(File input)
    throws JAXBException 
    {
        initializeJaxbContext();
        Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
        return (Company) unMarshaller.unmarshal(input);
    }

    public static void serializeCompany(File output, Company c)
    throws     JAXBException,
            FileNotFoundException,
            XMLStreamException 
    {
        initializeJaxbContext();
        OutputStream os = new FileOutputStream(output);
        Marshaller marshaller = jaxbContext.createMarshaller();
        XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os);
        marshaller.marshal(c, writer); // TODO: need a stream writer that does indentation
    }

Feature:Total and Feature:Cut are implemented as static methods:

public class Total {
    
    public static double total(Company c) {
        double total = 0;
        for (Department d : c.getDepartment())
            total += total(d);
        return total;
    }
    
    public static double total(Department d) {
        double total = total(d.getManager());
        for (Subunit s : d.getSubunit())
            total += total(s);
        return total;
    }

    public static double total(Employee e) {
        return e.getSalary();
    }

    //
    // We cannot use virtual methods.
    // That is, we do not allow ourselves modifying schema-derived classes.
    //
    public static double total(Subunit s) {
        if (s instanceof Department)
            return total(((Department)s));
        else if (s instanceof Employee)
            return total(((Employee)s));
        else throw new IllegalArgumentException();
    }

}
public class Cut {
    
    public static void cut(Company c) {
        for (Department d : c.getDepartment())
            cut(d);
    }

    public static void cut(Department d) {
        cut(d.getManager());
        for (Subunit s : d.getSubunit())
            cut(s);
    }

    public static void cut(Employee e) {
        e.setSalary(e.getSalary() / 2);
    }

    public static void cut(Subunit s) {
        if (s instanceof Department)
            cut(((Department)s));
        else if (s instanceof Employee)
            cut(((Employee)s));
        else throw new IllegalArgumentException();
    }

}

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Contribution:

jaxbSubstitution

Headline

Object-XML mapping for Language:Java and Language:XSD with Technology:JAXB

Characteristics

See Contribution:jaxbComposition for the overall motivation of exercising Technology:JAXB and for arguably a simple baseline of a schema and corresponding schema-derived classes. The present implementation represents an attempt to model different kinds of subunits of department (i.e., sub-departments and employees) as subtypes of a common supertype of subunits, where subtyping is meant here in the sense of XSD's substitution grouping mechanism. The result is rather complex at both ends.

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd). For example departments:

<xs:complexType name="department">
 <xs:complexContent>
  <xs:extension base="subunit">
   <xs:sequence>
    <xs:element ref="name"/>
    <xs:element name="manager" type="employee"/>
    <xs:element ref="subunit" maxOccurs="unbounded" minOccurs="0"/>
   </xs:sequence>
  </xs:extension>
 </xs:complexcontent>
</xs:complextype>

Actual Language:Java classes will be generated using Technology:xjc.

Feature:Open serialization is implemented using Technology:JAXB Un-/Marshaller:

    public static Company deserializeCompany(File input)
    throws JAXBException 
    {
        initializeJaxbContext();
        Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
        return (Company) unMarshaller.unmarshal(input);
    }

    public static void serializeCompany(File output, Company c)
    throws     JAXBException,
            FileNotFoundException,
            XMLStreamException 
    {
        initializeJaxbContext();
        OutputStream os = new FileOutputStream(output);
        Marshaller marshaller = jaxbContext.createMarshaller();
        XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os);
        marshaller.marshal(c, writer); // TODO: need a stream writer that does indentation
    }

Feature:Total and Feature:Cut are implemented as static methods:

public class Total {

	public static double total(Company c) {
		double total = 0;
		for (Department d : c.getDepartment())
			total += total(d);
		return total;
	}

	public static double total(Department d) {
		double total = total(d.getManager());
		for (JAXBElement<? extends Subunit> s : d.getSubunit())
			total += total(s.getValue());
		return total;
	}

	public static double total(Employee e) {
		return e.getSalary();
	}

	//
	// We cannot use virtual methods.
	// That is, we do not allow ourselves modifying schema-derived classes.
	//
	public static double total(Subunit s) {
		if (s instanceof Department)
			return total(((Department)s));
		else if (s instanceof Employee)
			return total(((Employee)s));
		else throw new IllegalArgumentException();
	}

}
public class Cut {

    public static void cut(Company c) {
        for (Department d : c.getDepartment())
            cut(d);
    }

    public static void cut(Department d) {
        cut(d.getManager());
        for (JAXBElement<? extends Subunit> s : d.getSubunit())
            cut(s.getValue());
    }

    public static void cut(Employee e) {
        e.setSalary(e.getSalary() / 2);
    }

    public static void cut(Subunit s) {
        if (s instanceof Department)
            cut(((Department)s));
        else if (s instanceof Employee)
            cut(((Employee)s));
        else throw new IllegalArgumentException();
    }

}

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Feature:

Cut

Headline

Cut the salaries of all employees in half

Description

For a given company, the salaries of all employees are to be cut in half. Let's assume that the management of the company is interested in a salary cut as a response to a financial crisis. Clearly, any real company is likely to respond to a financial crisis in a much less simplistic manner.

Motivation

The feature may be implemented as a transformation, potentially making use of a suitable transformation or data manipulation language. Conceptually, the feature corresponds to a relatively simple and regular kind of transformation, i.e., an iterator-based transformation, which iterates over a company' employees and updates the salaries of the individual employees along the way. It shall be interesting to see how different software languages, technologies, and implementations deal with the conceptual simplicity of the problem at hand.

Illustration

The feature is illustrated with a statement in Language:SQL to be applied to an instance of a straightforward relational schema for companies where we assume that all employees belong to a single company:

UPDATE employee
 SET salary = salary / 2;

The snippet originates from Contribution:mySqlMany.

Relationships

Guidelines

  • The name of an operation for cutting salaries thereof should involve the term "cut". This guideline is met by the above illustration, if we assume that the shown SQL statement is stored in a SQL script with name "Cut.sql". Likewise, if OO programming was used for implementation, then the names of the corresponding methods should involve the term "cut".
  • A suitable demonstration of the feature's implementation should cut the salaries of a sample company. This guideline is met by the above illustration, if we assume that the shown SQL statement is executed on a database which readily contains company data. Queries according to Feature:Total may be used to compare salaries before and after the cut. All such database preparation, data manipulation, and query execution should preferably be scripted. By contrast, if OO programming was used, then the demonstration could be delivered in the form of unit tests.

Feature:

Open serialization


Feature:

Total

Headline

Sum up the salaries of all employees

Description

The salaries of a company's employees are to be summed up. Let's assume that the management of the company is interested in the salary total as a simple indicator for the amount of money paid to the employees, be it for a press release or otherwise. Clearly, any real company faces other expenses per employee, which are not totaled in this manner.

Motivation

The feature may be implemented as a query, potentially making use of a suitable query language. Conceptually, the feature corresponds to a relatively simple and regular kind of query, i.e., an iterator-based query, which iterates over a company' employees and aggregates the salaries of the individual employees along the way. It shall be interesting to see how different software languages, technologies, and implementations deal with the conceptual simplicity of the problem at hand.

Illustration

Totaling salaries in SQL

Consider the following Language:SQL query which can be applied to an instance of a straightforward relational schema for companies. We assume that all employees belong to a single company; The snippet originates from Contribution:mySqlMany.

SELECT SUM(salary) FROM employee;

Totaling salaries in Haskell

Consider the following Language:Haskell functions which are applied to a simple representation of companies.

-- Total all salaries in a company
total :: Company -> Float
total = sum . salaries

-- Extract all salaries in a company
salaries :: Company -> [Salary]
salaries (n, es) = salariesEs es

-- Extract all salaries of lists of employees
salariesEs :: [Employee] -> [Salary]
salariesEs [] = []
salariesEs (e:es) = getSalary e : salariesEs es

-- Extract the salary from an employee
getSalary :: Employee -> Salary
getSalary ( ,  , s) = s

Relationships

Guidelines

  • The name of an operation for summing up salaries thereof should involve the term "total". This guideline is met by the above illustration, if we assume that the shown SQL statement is stored in a SQL script with name "Total.sql". By contrast, if OO programming was used for implementation, then the names of the corresponding methods should involve the term "total".
  • A suitable demonstration of the feature's implementation should total the salaries of a sample company. This guideline is met by the above illustration, if we assume that the shown SQL statement is executed on a database which readily contains company data. All such database preparation and query execution should preferably be scripted. Likewise, if OO programming was used, then the demonstration could be delivered in the form of unit tests.

Contribution:

jaxbComposition

Headline

Object-XML mapping with JAXB of the Java platform

Characteristics

Language:XML import and export is supported for a Java-based implementation by means of O/X mapping. The primary data model for companies is an XML schema. The schema compiler Technology:xjc of Technology:JAXB is used to generate Java classes from the schema. In this manner, operations on an XML representation of companies can be implemented in near-to-regular OO fashion while using a problem-specific object model. In different terms, one can carry out XML processing while essentially staying in the technological space of objectware. It is insightful to compare XML schema and schema-derived classes. The XML schema is defined in a manner that the resulting object model systematically leverages object composition and no class inheritance. In fact, the schema-derived classes are very similar to a regular OO design; see Contribution:javaComposition. It is important to note that the operations on companies are not implemented as instance methods since this would imply modification of schema-derived classes---unless advanced modularization mechanisms were leveraged. Instead, the operations are implemented as static methods in non-schema-derived classes.

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd). For example departments:

 <xs:element name="department">
  <xs:complexType>
   <xs:sequence>
    <xs:element ref="name"/>
    <xs:element name="manager" type="employee"/>
    <xs:element ref="department" maxOccurs="unbounded" minOccurs="0"/>
    <xs:element name="employee"
        type="employee" maxOccurs="unbounded" minOccurs="0"/>
   </xs:sequence>
  </xs:complextype>
 </xs:element>    

Actual Language:Java classes will be generated using Technology:xjc.

Feature:Open serialization is implemented using Technology:JAXB Un-/Marshaller:

    public static Company deserializeCompany(File input)
    throws JAXBException 
    {
        initializeJaxbContext();
        Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
        return (Company) unMarshaller.unmarshal(input);
    }

    public static void serializeCompany(File output, Company c)
    throws     JAXBException,
            FileNotFoundException,
            XMLStreamException 
    {
        initializeJaxbContext();
        OutputStream os = new FileOutputStream(output);
        Marshaller marshaller = jaxbContext.createMarshaller();
        XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os);
        marshaller.marshal(c, writer); // TODO: need a stream writer that does indentation
    }

Feature:Total and Feature:Cut are implemented as static methods:

public class Total {

	public static double total(Company c) {
		double total = 0;
		for (Department d : c.getDepartment())
			total += total(d);
		return total;
	}

	public static double total(Department d) {
		double total = total(d.getManager());
		for (Department s : d.getDepartment())
			total += total(s);
		for (Employee e : d.getEmployee())
			total += total(e);
		return total;
	}

	public static double total(Employee e) {
		return e.getSalary();
	}

}
public class Cut {

	public static void cut(Company c) {
		for (Department d : c.getDepartment())
			cut(d);
	}

	public static void cut(Department d) {
		cut(d.getManager());
		for (Department s : d.getDepartment())
			cut(s);
		for (Employee e : d.getEmployee())
			cut(e);
	}

	public static void cut(Employee e) {
		e.setSalary(e.getSalary() / 2);
	}

}

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Contribution:

jaxbChoice

Headline

Object-XML mapping for Language:Java and Language:XSD with Technology:JAXB

Characteristics

See Contribution:jaxbComposition for the overall motivation of exercising Technology:JAXB and arguably a simple baseline for a schema and the corresponding schema-derived classes. The present implementation exercises an XSD choice for different kinds of subunits. The schema-derived class Subunit encodes the choice in an arguably sub-optimal manner (as a result of the lack of a good match for XSD choices in the Java type system). One could expect that XSD choices (of a restricted kind) could be translated into class inheritance, but this does not happen here (and this may be understandable).

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd). For example departments:

 <xs:element name="department">
  <xs:complexType>
   <xs:sequence>
    <xs:element ref="name"/>
    <xs:element name="manager" type="employee"/>
    <xs:element ref="department" maxOccurs="unbounded" minOccurs="0"/>
   </xs:sequence>
  </xs:complextype>
 </xs:element>    

Actual Language:Java classes will be generated using Technology:xjc.

Feature:Open serialization is implemented using Technology:JAXB Un-/Marshaller:

    public static Company deserializeCompany(File input)
    throws JAXBException 
    {
        initializeJaxbContext();
        Unmarshaller unMarshaller = jaxbContext.createUnmarshaller();
        return (Company) unMarshaller.unmarshal(input);
    }

    public static void serializeCompany(File output, Company c)
    throws     JAXBException,
            FileNotFoundException,
            XMLStreamException 
    {
        initializeJaxbContext();
        OutputStream os = new FileOutputStream(output);
        Marshaller marshaller = jaxbContext.createMarshaller();
        XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os);
        marshaller.marshal(c, writer); // TODO: need a stream writer that does indentation
    }

Feature:Total and Feature:Cut are implemented as static methods:

public class Total {

    public static double total(Company c) {
        double total = 0;
        for (Department d : c.getDepartment())
            total += total(d);
        return total;
    }

    public static double total(Department d) {
        double total = total(d.getManager());
        for (Subunit s : d.getSubunit())
            total += total(s);
        return total;
    }

    public static double total(Employee e) {
        return e.getSalary();
    }

    public static double total(Subunit s) {
        double total = 0;
        if (s.getEmployee() != null) total += total(s.getEmployee());
        if (s.getDepartment() != null) total += total(s.getDepartment());
        return total;
    }

}
public class Cut {
    
    public static void cut(Company c) {
        for (Department d : c.getDepartment())
            cut(d);
    }

    public static void cut(Department d) {
        cut(d.getManager());
        for (Subunit s : d.getSubunit())
            cut(s);
    }

    public static void cut(Employee e) {
        e.setSalary(e.getSalary() / 2);
    }

    public static void cut(Subunit s) {
        if (s.getEmployee()!=null) cut(s.getEmployee());
        if (s.getDepartment()!=null) cut(s.getDepartment());
    }

}

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Headline

Exercise in-memory XML processing with Technology:XOM in Language:Java

Characteristics

See Contribution:dom for a general motivation for exercising in-memory XML processing. The present implementation simply exercises yet another DOM-like API. We end up providing a descendants axis to this end.

Illustration

The data model is implemented as xml files (sampleCompany.xml) that conform to a schema (Company.xsd).

Feature:Open serialization is implemented using Technology:xom Builder:

    public static Element deserializeCompany(String file) throws ValidityException, ParsingException, IOException {
        return (new Builder().build(new File(file)).getRootElement());
    }

Feature:Total and Feature:Cut are implemented by using descendants:

	public static double total(Element elem) {
		double total = 0;
		for (Element s : descendants(elem, "salary"))
			total += Double.valueOf(s.getValue());
		return total;
	}

	public static void cut(Element elem) {
		for (Element s : descendants(elem, "salary")) {
			double value = Double.valueOf(s.getValue());
			value /= 2;
			s.removeChildren();
			s.appendChild(new Text(Double.toString(value)));
		}
	}

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
    • org.softlang.company.features for implementations of Functional requirements.
      • org.softlang.company.features.xom for descendants helper.
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Contribution:

xpathAPI

Headline

Exercise XML processing with Language:XPath embedded in Language:Java

Characteristics

Companies are represented in Language:XML and processed by XPath and Java. XPath is embedded into Java code which makes it possible to process query results in Java. Query results are bound to DOM-like node sets, and one can iterate over those and mutate them, thereby implementing impure transformations.

Illustration

The data model is implemented as xml files (sampleCompany.xml).

Feature:Open serialization is implemented using Technology:DOM Document objects:

    /**
     * Load a document from a file
     */
    public static Document loadDocument(String filename) {
        try {
            // Create a builder factory
            DocumentBuilderFactory factory = 
                DocumentBuilderFactory.
                newInstance();

            // Create the builder
            DocumentBuilder builder =
                factory.
                newDocumentBuilder();

            // Deserialization by parsing
            Document doc =
                builder.
                parse(new File(filename));

            // Done
            return doc;

        } catch (SAXException e) {
        } catch (ParserConfigurationException e) {
        } catch (IOException e) {
        }
        
        // Return null for any sort of problem
        return null;
    }
    /**
     * Save a document to a file.
     */
    public static boolean saveDocument(Document doc, String filename) {

        try {

            // Prepare the DOM document for writing
            Source source = new DOMSource(doc);

            // Prepare the output file
            File file = new File(filename);
            Result result = new StreamResult(file);

            // Creater a transformer factory
            TransformerFactory xfactory = 
                TransformerFactory.
                newInstance();

            // Create a transformer
            Transformer transformer = 
                xfactory.
                newTransformer();

            // Force pretty printing
            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

            // Serialization by transformation
            transformer.transform(source, result);

            // Done
            return true;

        } catch (TransformerConfigurationException e) {
        } catch (TransformerException e) {
        }

        // Return false for any sort of problem
        return false;
    }

Feature:Total and Feature:Cut are implemented by using Technology:DOM trees and Language:XPath queries:

    public static double total(Document doc) 
        throws Exception {

        // The aggregation variable 
        double total = 0;

        // Get the matching elements
        NodeList nodelist = XPathAPI.selectNodeList(doc, "//salary");

        // Process the elements in the nodelist
        for (int i=0; i<nodelist.getLength(); i++) {
            // Get element
            Element elem = (Element)nodelist.item(i);
            total += Double.parseDouble(elem.getTextContent());
        }
        return total;
    }

Fragment not found

The Language:XPath processor is implemented by Technology:Xalan-Java.

Test cases are implemented for all Namespace:Features.

Relationships

For DOM-like implementations of in-memory XML processing see Contribution:dom, Contribution:jdom and Contribution:xom.

For a query-based implementation of in-memory XML processing see Contribution:xpathAPI.

For push-based XML processing see Contribution:sax.

For Object/XML mapping see Contribution:jaxbChoice (XSD with choice for different subunits), Contribution:jaxbComposition (XSD with object composition), Contribution:jaxbExtension (XSD with type extension) and Contribution:jaxbSubstitution (XSD with substitution groups).

Architecture

The contribution follows a standardized structure:

  • inputs contains input files for tests
  • src/main/java contains the following packages:
  • src/test/java contains the following packages:

Usage

This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.

See https://github.com/101companies/101simplejava/blob/master/README.md


Namespace:

Feature

Headline

The namespace for software features of systems on 101wiki

Description

101wiki hosts (documentation of) features of software systems. The members of the Namespace:Feature are feature descriptions. Features need to be described. In the case of features for System:Company, the features need to be motivated. Features may be illustrated.


Technology:

Eclipse


Technology:

Gradle

Headline

A build tool inspired by Ant and Maven


Technology:

JUnit

Headline

A framework for unit testing for Language:Java