Contribution:
xom
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.
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
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
Illustration
Let's show "Hello World" for Java.
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
Contribution:
dom
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:
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases.
Usage
This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.
See https://github.com/101companies/101simplejava/blob/master/README.md
Contribution:
jdom
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
- 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).
- Contribution:jdomHttp uses HTTP-based access to the input data instead of going through the file system.
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.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
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
Contribution:
sax
Headline
Push-based XML parsing in Language:Java with Technology:SAX
Characteristics
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:
- org.softlang.company.features for implementations of Functional requirements.
- org.softlang.company.features.sax for additional Technology:sax functionality.
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
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:
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
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:
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
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
- See Feature:Total for a query scenario instead of a transformation scenario.
- In fact, Feature:Total is likely to be helpful in a demonstration of Feature:Salary cut.
- The present feature should be applicable to any data model of companies, specifically Feature:Flat company and Feature:Hierarchical_company.
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
- See Feature:Cut for a transformation scenario instead of a query scenario.
- See Feature:Depth for a more advanced query scenario.
- The present feature should be applicable to any data model of companies, specifically Feature:Flat company and Feature:Hierarchical_company.
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:
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
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:
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
Usage
This contribution uses Technology:Gradle for building. Technology:Eclipse is supported.
See https://github.com/101companies/101simplejava/blob/master/README.md
Contribution:
xom
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.
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
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;
}
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:
- org.softlang.company.features for implementations of Functional requirements.
- src/test/java contains the following packages:
- org.softlang.company.tests for Technology:JUnit test cases for Namespace:Features.
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.