Welcome to SOJO

Make everything as simple as possible, but not simpler. (Albert Einstein)

SOJO stands for Simplify your Old Java Objects or, in noun form, Simplified Old Java Objects.

The intention for this project is a Java framework, that convert JavaBeans in a simplified representation. So it is easy and uniform to handle and control the access to JavaBeans properties.

The goal of the SOJO project is to provide a library to convert object graphs into a specific structure (manages cycle detection, as well). The framework provide a "pluggable" basis to integrate different kind of conversions (so even custom formats can be used). With this infrastructure can solve problems, where POJOs are not supported or not the best decision.

Requirement

This framework is developed und tested with JavaTM 2 Platform Standard Edition, v 1.4.2.

The SOJO framework has no dependencies to external libraries !!!

Only for the optional - packages (extensions) are external libraries required.

Are Plain Old Java Objects (POJOs) to complex?

POJOs are very important for the development. With POJOs you can develop object oriented and independent from often changed technologies.

But what is with cases, where Java must communicate with "other worlds"? Other worlds are interfaces, where object orientation is not supported or is not the best decision.

This environments are part of the SOJO framework.

Supported SOJO functionality

  • data interchange to easy communication with non-Java processes:
    • JSON (JavaScript Object Notation) a lightweight data-interchange format
    • Object To XML - where is XML-RPC a special case
    • Java serialization, without implements the interface java.io.Serializable (e.g. cluster, cache, remote communication, ...)
    • Comma Separated Values (CSV) - Request for Comments: 4180
    • Serializer serializer = new JsonSerializer(); 
      // XmlRpcSerializer | CsvSerializer | ObjectSerializer 
      Object result = serializer.serialize(anObject);
      Object anObjectCopy = serializer.deserialize(result);
      
      Car car = new Car("my car");
      car.setBuild(new Date());
      car.setDescription("This is my car");
      
      // simple filtering of properties (build, description)
      Serializer serializer = new JsonSerializer(); 
      Object result = serializer.serialize(car, new String[] { "build", "description" });
      Car carAfter = (Car) serializer.deserialize(result);
      
      assertEquals("my car", carAfter.getName());
      assertNull(carAfter.getDescription());
      assertNull(carAfter.getBuild());
      
  • operations with complex Java-Objects-graphs (common / navigation):
    • copy or clone complex object graph (for data transfer objects (DTO), can manage different versions from one object graph (object history))
      Object anObjectCopy = new ObjectUtil().copy(anObject);
      
    • compare complex object graph
      // for example for the equals method, compare all values
      public boolean equals(Object obj) {
        return new ObjectUtil().equals(obj, this);
      }
      
      // the complement, the hashCode - method
      public int hashCode() {
        return new ObjectUtil().hashCode(this);
      }
      
      // show the first finded different value
      CompareResult result = new ObjectUtil().compare(obj1, obj2);
      
      // show all finded different value
      CompareResult result[] = new ObjectUtil().compareAll(obj1, obj2);
      
      // less, equal, greater (for JavaBeans too)
      int compareTo = new ObjectUtil().compareTo(obj1, obj2);
      
    • sort lists, arrays, set and maps of objects
      Car cars[] = new Car [] { new Car("Ferrari"), new Car("Audi"), new Car("BMW") } ;
      cars = (Car[]) IterateableUtil.sort(cars);
      assertEquals("Audi", cars[0].getName());
      assertEquals("BMW", cars[1].getName());
      assertEquals("Ferrari", cars[2].getName());
      
    • easy navigate on the complex object graph (with a navigation language)
      Object result = PathExecuter.getNestedProperty(node, "childs[0].name");
      
    • Convert objects (respectively object graphs)
      // transform a Exception to a Map, what is usefull by client/server applications, 
      // to transport the value over the network
      ObjectUtil util = new ObjectUtil();
      Map throwableMap = (Map) util.makeSimple(new ConversionException("Test"));
      ConversionException conversionException = (ConversionException) util.makeComplex(throwableMap);
      
      // or transform to an other Exception, what is usefull by client/server applications,
      // where the client doesn't know the server Exception  (e.g. DaoException/TechnicalException)
      ClientException clientException = (ClientException) util.makeComplex(throwableMap, ClientException.class);
      
      // transform to a formatted String
      util.addFormatterForType(new SimpleDateFormat("dd-MM-yyyy"), Date.class);
      Object str = util.makeSimple(new Date());
      
      // transform a String to a Long value
      Converter converter = new Converter();
      converter.addConversion(new Simple2SimpleConversion(String.class, Long.class));
      String s = "57";
      Long result = (Long) converter.convert(s);
      
    • walk over object graph (to traverse)
      						
      ObjectGraphWalker walker = new ObjectGraphWalker();
      PathRecordWalkerInterceptor interceptor = new PathRecordWalkerInterceptor();
      walker.addInterceptor(interceptor);
      		
      walker.walk(anObjectGraph);
      Map visitedPathes = interceptor.getAllRecordedPathes();
      

SOJO functionality for the future

  • operations with complex Java-Objects-graphs:
    • extend objects to additional information (e.g.: object-versions (number of changes), data changed date or changed user)
    • mapping from one property to other property (name to name mapping (by naming conflicts) or value to value mapping (to convert values))
    • making object-values immutable, for testing concurrent access - multi threading)
  • remote acces/communication:
    • HTTP protocol - request and response are based on String represantation
    • RMI (Java-Object must serializable (marshalling) or deserializable (unmarshalling))
    • WebService or XML RPC - convert Java-Object in special String represantation, in XML
    • create "value objects" or "transfer objects" to sent objects over the network
  • data access:
    • object/relational persistence respectively object/relational mapping
    • flat files (convert Java-Object-Graph to a flat represantation)
    • property files (e.g. convert Strings to Long, Date, ... by reading a property file and map the value to setter from a Bean)
    • legacy systems
  • GUI interface:
    • transform business models to GUI-models (DataBinder)
    • every changes on the GUI-model must to notice (integrated PropertyChangeListener or VetoableChangeListener)
  • and so on ...

In cases, where object orientation and not object orientation must work together, exist the problem of independent mismatched. The SOJO framework want to do this problem a little bit smaller.