GATE: A working example for gate.corpora.DocumentJsonUtils - gate

I have been trying to understand how to use the JSON exporter in GATE located in gate.corpora.DocumentJsonUtils. Can someone supply a working example? I am not quite sure where to find or how to construct the Map<String,Collection<Annotation>> annotationsMap which is required by all the methods.

Here is the "quick" hack that solved it for me. Not sure why they decided on this particular data structure. Also not sure why this is not done internally as a default option as it is derived from the document.
¯\_(ツ)_/¯
public static String makeJson(Document doc) {
AnnotationSet as = doc.getAnnotations();
Map<String, Collection<Annotation>> anns = new HashMap<>();
anns.put("MyAnnotations", as.inDocumentOrder());
try {
return DocumentJsonUtils.toJson(doc, anns);
} catch (IOException ex) {
return "";
}
}

Related

Recommended Access Modifiers for Testability of Wrapper Methods

One thing I have started doing in my tests is to wrap error messages and string concatenations into methods or variables to keep my tests robust should the error message contents change later.
So for example, I would refactor something like this:
try{
someMethod();
}catch(e){
throw new Error('error message.');
}
into this:
let errorMessage = 'error message';
...
try{
someMethod();
}catch(e){
throw new Error(errorMessage);
}
Or something similar if the error message contains a variable or something.
My question is what would be the best way to do this in Typescript? In Java I would have them be package-protected, but here it seems Jasmine does not have access to methods like this if they are protected. I have also tried making them static.
Is there preferred method for this?
This is one occasion where you can transfer some good practices from other languages.
If you create custom exceptions, you can test their type, rather than the strings - and you can also ensure uniformity of error messages.
This example looks a bit convoluted, but it should give you an idea (adapted from page 163-168 Pro Typescript).
A base CustomException class is created that implements the Error interface and will sit beneath any custom error types we want in our application.
An InvalidDateException is created to represent a particular class of error, this is the only place the error message string needs to be stored in the application.
You can now look at particular kinds of error as in the example catch statement where instanceof is used to check the type.
All your custom exceptions are compatible with the Error interface, which required name and toString().
Code:
class CustomException implements Error {
protected name = 'CustomException';
constructor(public message: string) {
}
toString() {
return this.name + ': ' + this.message;
}
}
class InvalidDateException extends CustomException {
constructor(public date: Date) {
super('The date supplied was not valid: ' + date.toISOString());
this.name = 'InvalidDateException';
}
}
try {
throw new InvalidDateException(new Date());
} catch (ex) {
if (ex instanceof InvalidDateException) {
alert(ex.toString());
}
}

Java CXF: What is the best way to handle Common Objects under different packages or namespaces?

We're integrating with a 3rd Party webservice by using Wsdl2Java to translate their Schema and endpoints into Java for three different webservices that they offer.
This particular provider uses a lot of the same objects (think objects representing an Address, Money, Weight, etc), but, in their infinite wisdom, they've decided to create a different namespace for each webservice and duplicate the definition of their schemas for each one. The result is you have the following classes output for CXF integration:
com.thirdpartyguys.api.firstApi.Money
com.thirdpartyguys.api.secondApi.Money
com.thirdpartyguys.api.thirdApi.Money
Translating our data into theirs can involve a lot of business logic and, as a result, we have to define the code that creates the objects in triplicate for each individual Webservice API.
To overcome this problem I created an Interface defined thusly:
import org.apache.commons.beanutils.BeanUtils;
public interface CommonObjectInterface<A, R, S> {
A toFirstApi();
R toSecondApi();
S toThirdApi();
default Object doTransform(Object destination, Object source) {
try {
BeanUtils.copyProperties(destination, source);
} catch (Exception e) {
throw new RuntimeException("Fatal error transforming Object", e);
}
return destination;
}
}
You would then have each common object implement the interface, define its own constructors, fluent API, etc, and call the toXXX() methods to get the proper form of the object for the respective API.
Right now most of these implementing classes work by keeping a copy of one of the Apis locally, setting data on that, and then transforming it for the proper API using the doTransform() method which in its default form uses the Apache Commons BeanUtils.copyProperties() method.
It's more elegant than having the same code exist in three different places, but not by much! There's a lot of boilerplate and, even though this won't be getting hammered too much, not that efficient.
I would like to get feedback from the community as to whether this is a good idea or if there are better approaches. A similar question was asked years ago here, but I don't know if better solutions have emerged since it was asked. I imagine the best thing would be configuring wsdl2Java to allow setting the namespace at runtime, but from my initial research this does not seem to be possible.
The solution to this problem is specific to this exact situation:
1) A webservice provider that has the same object in different namespaces
2) Using wsdl2Java or some underlying Apache CXF technology to generate the web artifacts for writing a client.
This is a fringe case so I'm not sure how helpful this will be to the community but the trick is to account for a few situations where a copyProperties method doesn't work. In this case I'm using Spring's BeanUtils and BeanWrapper classes although I'm sure this could be adapted for Apache as well. The following code does the trick:
final String TARGET_PACKAGE = "com.thirdpartyguys.api";
public Object doTransform(Object destination, Object source) {
/*
* This will copy all properties for the same data type for which there is a getter method in
* source, and a setter method in destination
*/
BeanUtils.copyProperties(source, destination);
BeanWrapper sourceWrapper = new BeanWrapperImpl(source);
for(PropertyDescriptor p : sourceWrapper.getPropertyDescriptors()) {
/*
* Properties that are references to other schema objects are identical in structure, but have
* different packages. We need to copy these separately
*/
if(p.getPropertyType().getPackage().getName().startsWith(TARGET_PACKAGE)) {
try {
commonPropertyCopy(destination, source, p);
} catch (Exception e) {
throw new RuntimeException("Fatal error creating Data", e);
}
}
/*
* Properties that reference list don't create setters according to the Apache CXF
* convention. We have to call the get method and addAll()
*/
else if(Collection.class.isAssignableFrom(p.getPropertyType())) {
try {
collectionCopy(destination, source, p);
} catch (Exception e) {
throw new RuntimeException("Fatal error creating Data", e);
}
}
}
return destination;
}
private void collectionCopy(Object destination, Object source, PropertyDescriptor sourceProperty) throws Exception {
BeanWrapper destWrapper= new BeanWrapperImpl(destination);
PropertyDescriptor destProperty = destWrapper.getPropertyDescriptor(sourceProperty.getName());
Collection<?> sourceCollection = (Collection<?>) sourceProperty.getReadMethod().invoke(source);
Collection<Object> destCollection = (Collection<Object>) destProperty.getReadMethod().invoke(destination);
destCollection.addAll(sourceCollection);
}
private void commonPropertyCopy(Object destination, Object source, PropertyDescriptor sourceProperty) throws Exception {
if(sourceProperty.getPropertyType().isEnum()) {
instantiateEnum(destination, source, sourceProperty);
}
else {
instantiateObject(destination, source, sourceProperty);
}
}
private void instantiateEnum(Object destination, Object source, PropertyDescriptor sourceProperty) throws Exception {
BeanWrapper destWrapper= new BeanWrapperImpl(destination);
Enum<?> sourceEnum = (Enum<?>) sourceProperty.getReadMethod().invoke(source);
PropertyDescriptor destProperty = destWrapper.getPropertyDescriptor(sourceProperty.getName());
Object enumValue = Enum.valueOf(destProperty.getPropertyType().asSubclass(Enum.class), sourceEnum.name());
destProperty.getWriteMethod().invoke(destination, enumValue);
}
private void instantiateObject(Object destination, Object source, PropertyDescriptor sourceProperty) throws Exception {
Object subObj = sourceProperty.getReadMethod().invoke(source);
if(subObj!=null) {
BeanWrapper destWrapper = new BeanWrapperImpl(destination);
String subObjName = sourceProperty.getName();
PropertyDescriptor destProperty = destWrapper.getPropertyDescriptor(subObjName);
Class<?> propertyType = destProperty.getReadMethod().getReturnType();
Object subObjCopy = propertyType.getConstructor().newInstance();
doTransform(subObjCopy, subObj);
destProperty.getWriteMethod().invoke(destination, subObjCopy);
}
}
instantiateObject is used to create new instances of the "identical" objects from different packages. This also applies for Enumerated types and requires its own method, hence the implementation of instantiateEnum. Finally, the default CXF implemenation offers no setter method for Lists. We handle this situation in collectionCopy.

is this valid Factory pattern usage?

I made PageFactory class for Paging the list of data regardless which DBMS is used.
But I'm not sure that this is valid factory pattern or something's wrong.
If there's better way to to this could you tell me?
package com.tource.cms.common.database.paging;
import com.tource.cms.common.environment.EnvironmentVariables;
public class PageFactory {
private static final String DEFAULT_DATABASE_TYPE = getDefaultDatabaseType();
public static Page createPage(int totalRow, int currPage, int blockRow, int blockPage) {
if("mysql".equals(DEFAULT_DATABASE_TYPE))
return new MysqlPageCalculator(totalRow, currPage, blockRow, blockPage).getPage();
else if("oracle".equals(DEFAULT_DATABASE_TYPE))
return new OraclePageCalculator(totalRow, currPage, blockRow, blockPage).getPage();
else {
try {
throw new UnsupportedDatabaseException();
} catch (UnsupportedDatabaseException e) {
e.printStackTrace();
return null;
}
}
}
/** getting DBMS type from cached Memory */
private static String getDefaultDatabaseType() {
return EnvironmentVariables.get("cms.jdbc.databaseType").toLowerCase();
}
}
As long as MysqlPageCalculator and OraclePageCalculator implement the same interface, or the same super class, let's say PageCalculator, you are implementing Abstract Factory pattern correctly.
As you have extract the creation process of page into a standalone class instead key word 'new'. So yes, it is a Simple Factory pattern.

Alternative of using built-in object that implements IDictionary for a web method

I have a web application that uses the Web Service created in ASP.NET. In this, web service I want to pass an collection object of Key Value type (i.e. something like Hashtable or Dictionay).
But we cannot use objects that implements from IDictionary.
I do not want to create a serialized class in my web service.
Can anyone suggest me the best approach for this?
dev.e.loper is almost right. You can use a List<Pair>.
Alternatively, you can use List<KeyValuePair<TKey,TValue>>.
MSDN Documentation:
KeyValuePair
Pair
I'm not totally clear on your question, but maybe you are needing something like this?
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
var keySerializer = new XmlSerializer(typeof(TKey));
var valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
{
return;
}
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
reader.ReadStartElement("key");
var key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement("value");
var value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer)
{
var keySerializer = new XmlSerializer(typeof(TKey));
var valueSerializer = new XmlSerializer(typeof(TValue));
foreach (var key in this.Keys)
{
writer.WriteStartElement("item");
writer.WriteStartElement("key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
writer.WriteStartElement("value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
}
You can inherit from KeyedCollection which is Serializable.
http://msdn.microsoft.com/en-us/library/ms132438.aspx
I solved this by using DictionaryEntry
The only difference is that Key is Object as well.
I basically have a Dictionary ToDictionary(DictionaryEntry[] entries) and a DictionaryEntry[] FromDictionary(Dictionary entries) static methods which are very light weight and end up getting me to the same place without having to make my own collection class.
The added benefit is that the XML which comes as a result is closer to that in which the WCF Web Services use by default! That means you can make this change now in your client code and be ready for WCF if you decide to move that way.
The result looks like this over JSON [{"Key": key1, "Value": value1}, {"Key": key2, "Value": value2}] exactly the same as it does over WCF by default.
You could try to use 2 arrays, 1 for keys and one for values, where the indexes of the arrays match up. Not the most ideal solution but a valid one. The internals of the webservice you can use IDictionary and just pass out the Keys and Values of that object.

Moq tests using ExpectSet() with It.Is<T>() aren't behaving as... expected

I've isolated the behaviour into the following test case. I'd be grateful to anyone who can tell me how to expect/verify a property set for a List<T> property - it appears there's something going on inside It.Is<T>(predicate) that isn't making a whole lot of sense to me right now. Sample code will run as a console app from VS2008 - you'll need to add a reference to Moq 2.6 (I'm on 2.6.1014.1) - please try uncommenting the different ExpectSet statements to see what's happening...
using System;
using Moq;
using System.Collections.Generic;
namespace MoqDemo {
public interface IView {
List<string> Names { get; set; }
}
public class Controller {
private IView view;
public Controller(IView view) {
this.view = view;
}
public void PopulateView() {
List<string> names = new List<string>() { "Hugh", "Pugh", "Barney McGrew" };
view.Names = names;
}
public class MyApp {
public static void Main() {
Mock<IView> mockView = new Mock<IView>();
// This works - and the expectation is verifiable.
mockView.ExpectSet(mv => mv.Names);
// None of the following can be verified.
// mockView.ExpectSet(mv => mv.Names, It.Is<Object>(o => o != null));
// mockView.ExpectSet(mv => mv.Names, It.Is<List<string>>(names => names.Count == 3));
// mockView.ExpectSet(mv => mv.Names, It.IsAny<IList<String>>());
Controller controller = new Controller(mockView.Object);
controller.PopulateView();
try {
mockView.VerifyAll();
Console.WriteLine("Verified OK!");
} catch (MockException ex) {
Console.WriteLine("Verification failed!");
Console.WriteLine(ex.Message);
}
Console.ReadKey(false);
}
}
}
}
I'm not using the very latest version of Moq, so I don't have an overload of ExpectSet that takes two parameters, but I've had some success with this pattern:
mockView.ExpectSet(mv => mv.Names).Callback(n => Assert.That(n != null));
The Assert (from NUnit) call in the callback will throw an exception if the value assigned to .Names doesn't match the predicate. It does make it hard to trace when a test fails, though. I agree that the ability to pass an It.Is or It.IsAny as the second parameter would be handy.
The second parameter of ExpectSet() is the value you're expecting. You can't use It.Is<T> in this case as there's no overload that takes a predicate - though it would be nice ;) Here's a (simplified) excerpt from your sample, illustrating the use of a value:
var mockView = new Mock<IView>();
var list = new List<string> { "Hugh", "Pugh", "Barney McGrew" };
mockView.ExpectSet(mv => mv.Names, list);
mockView.Object.Names = list;
Hope that helps.
Edit: fixed typo.
BTW, It.Is is not supported on ExpectSet. Your code compiles just because they are regular method invocations when used as values (as opposed to expressions), whereas when used in an Expect expression they are pre-processed by Moq and given specific meaning (rather than the null/default value that all It.Is members actually return).
You could use the stub behavior on the given property (mockView.Stub(mv => mv.Names)) and later assert directly for its value after execution.
Moq doesn't provide an overload receiving It.IsAny as it's effectively the same as calling ExpectSet without passing an expected value ;)