How to implement Dicom attribute dictionary in my own API - java

Greetings,
I am currently trying to learn some Java programming. To do this I'm trying to make something actually useful. Because I'm studying Medical Imaging, I though I would write my own Dicom Api in Java.
Part of the Dicom Standard is a Data Dictionary containing attributes used in Dicom Files. These attributes have to following properties.
(Group,Element) Description
For example:
(0x0002,0x0000) Length
(0x0002,0x0002) MediaStoredSOPClassUID
(0x0002,0x0010) TransferSyntaxUID
(0x0003,0x0003) Length
I was wondering how I should implement these in my API. The options I have thought of are:
Enum, problem with that is that unique attributes could have the same description.
enum Attributes{
Length(0x0002,0x0000),
Length(0x0003,0x0000,
}
A static class with just some constants containing the properties. Also the problem with the names excists.
A xml file containing this data.
I really would like to use xml for this, because of the tabularity of the data and easy access. But is there any way I can include this in my Api.
~Timo Willemsen

To ease the access, the XML file should be placed in the classpath so that you can get its location by ClassLoader#getResource() or its contents by ClassLoader#getResourceAsStream().
To read/evaluate/write the XML file with a standard API, I can recommend StAX. If the XML file is relatively large (over tens of megabytes), then I can recommend VTD-XML more.
Alternatively, if the file is not so large and it are pure key-value pairs, then you can also consider properties files, which you can easily manage with java.util.Properties API which basically extends Map.

a map will work best for you, define a class that will hold a dicom entry :
public class DicomEntry
{
private:
private string group;
private string element;
private string vr;
private string name;
public string key() { return String.format("(%s,%s)",group,element); }
}
also create a map that will hold all the entries
Map<string,DicomEntry> mp=new HashMap<string, DicomEntry>();
after reading each line from your dictionary file into an entry class object de add it the map
mp.put(de.key(), de)
since the combination of group and element is unique you wound have any collisions

You might also want to study other DICOM sources. PixelMed, in particular, contains an XML and XSLT based validator. Several DICOM plugins are available for ImageJ.

Here is PS 3.6-2008 as XML as used in GDCM:
http://gdcm.svn.sf.net/viewvc/gdcm/trunk/Source/DataDictionary/Part6.xml?view=markup
As mentionned above, I would also add VM and Retired flag:
public class DicomEntry { private:
private ushort group;
private ushort element;
private string vr;
private string vm;
private boolean retired;
private string name;
public string key() { return String.format("(%s,%s)",group,element);
} }

Related

How to generate HTML file from Java class without hard coding HTML tags in the class?

I want to generate one HTML file form a String content.
But I do not want to hard code HTML tags (like <html>, <body>, <tr>, <td> etc.) in the Java class. In the same time, I also do not want to use any third party library for it.
It is a simple Java project (there is no web project flavor).
In my mind, I am thinking of using a properties file to configure all HTML tags and use those properties in my Java class.
If anyone has any other way to do this, please suggest me through a simple example.
I've been experimenting along these lines for one of my projects (producing an image of a receipt, going through HTML/CSS because wkhtmltopdf can render it as a PNG). I think you will find that trying to abstract your string generator to handle potential future output of CSV, XML, etc. will over-complicate your method. I have objects right now that I deal with via JSON, XML, and HTML, and they all require different approaches. For JSON, I rely on Spring's conversion. For XML, I use JAXB. For HTML, I have been doing what a couple of people mentioned in comments with templates.
e.g.
String template = "<html><head/><body><h1>Hello %s</h1></body></html>";
System.out.println(String.format(template, "World");
As also suggested in the comments, you could load that template string from a file, but this will become complicated very quickly, such as if you have objects within your first object which need to generate their own HTML:
public Class Container{
private String name;
private OtherClass other;
public convertToHtml(){
String template = "<html><head/><body><h1>Hello %s. Other: %s</h1></body></html>";
return String.format(template, name, other.convertToHtml());
}
}
public Class OtherClass{
private String stuff;
public convertToHtml(){
String template = "<span>%s</span>";
return String.format(template, stuff);
}
}

Which pattern to use reading from configuration and start different runners using Java

I have simple problem and want advice how to improve the design I will try not to give details of my implementation but to be more abstract.
I have a configuration file with xml structure.(but can be changed)
<configurations>
<conf>
<path1></path1>
<path2></path2>
<conf>
<conf>
<path1></path1>
<path2></path2>
<conf>
</configurations>
where path1 and 2 are paths to some files which are needed in the business logic where I do repeatable actions with this paths many times(like banchmarks)
Then using this paths I need to do some operations but the content of every conf is separated from one another they can run in parallel without problems.
So first I read the configuration and store them in a List and then iterate over the list and execute consecutively the business logic.
I am wondering how can I improve the design of my decision?
I think I can use Iterator patter to iterate over the structure and to accomplished the repeatable logic for every cong to use the Strategy pattern.
Am wondering how to separate logic to use different runners for operations in every conf tag?
I think in many things that could be change for your implementation.
It's important to take the parts that vary and encapsulate them, by this way, later, you can alter or extend the parts that vary without affecting
those that don’t.
The parts that I suppose that could change are :
The source of your conf, it could come from a file (XML, CSV, XLSX, Properties File ...), your data base, etc.
The configuration. New attributes could be added to one conf.
Maybe you don't go to use all the configurations, so I vote for load some configuration when you need this one.
If one business logic needs one conf from your xml file and another business logic needs one conf from your csv file, your flexibility is not the best.
I propose the use of an utility class with the methods that you need to create/load your configuration from different sources.
I suppose that each conf has a name or an id. You could also add more properties as the list of path, the source type, etc.
A map is a better option to store your configurations. You could use a key as (confName, SourceType).
You could use MultiKey from (apache.commons) to create the key of your map.
Ex:
Multikey key = new Multikey(confName, sourceType);
You could create an enum for the source types:
public enum SourceType {
XML,
HTML,
CSV,
ORACLE_DB,
PROPERTIES;
}
Create one Singleton as utility class to create and load your configurations.(I recommend you to read the section of "Singleton" in the book Effective Java)
public enum ConfigurationLoader {
INSTANCE;
private Map<Multikey<String, SourceType>, Configuration> configurations = new HashMap<>();
public Configuration getConfiguration(String confName, SourceType sourceType) {
Multikey<String, SourceType> key = new Multikey<>(confName, sourceType);
if (!isConfigurationLoaded(key)) {
loadConfiguration(confName, sourceType);
}
return configurations.get(key);
}
//helper meethod to know if the configuration has been loaded
private boolean isConfigurationLoaded(Multikey<String, SourceType> key) {
return configurations.get(key) != null;
}
private void loadConfiguration(String confName, SourceType sourceType) {
if (SourceType.XML == sourceType) {
loadConfigurationFromXml(confName);
return;
}
if (SourceType.CSV == sourceType) {
loadConfigurationFromCSV(confName);
return;
}
if (SourceType.ORACLE_DB == sourceType) {
loadConfigurationFromOracleDb(confName);
return;
}
}
private void loadConfigurationFromXml(String confName) {
//your imlementation to create the configuration from XML file
// at the end you put the conf in the map
//.....
//configurations.put(key, configuration);
}
//Equals for the others methods
//private Configuration loadConfigurationFromCsv(String confName) { ....}
//private Configuration loadConfFromDb(String confName){...}
}
The Configuration class (I think that you need only this class, you go to have only fields to add and not behaviors):
public class Configuration {
private String name;
private SourceType sourceType;
private List<String> paths = new ArrayList<String>();
public Configuration(String name, SourceType sourceType) {
super();
this.name = name;
this.sourceType = sourceType;
}
public void addPath(String path) {
paths.add(path);
}
public List<String> getPaths() {
return paths;
}
}
You need to know the configuration that you want,so in your business layer, you could call your configuration as:
Configuration configuration = ConfigurationLoader.INSTANCE.getConfiguration(confName, SourceType.XML);
Next step, create your threads and iterate over you business logic with your configuration...
Hm, sounds a bit like you are desparately trying to apply design patterns to everything :)
(Which is actually not a bad thing as long as your main goal is to learn about patterns.)
As for the Iterator pattern, ok, you store your data in a list and somehow iterate over it. I would not call this applying the Iterator pattern. Iterators are already defined for most containers of the standard library. In most cases you do not directly use these. It is much more convenient to use an enhanced for loop or Java 8 streams, which can also automatically parallelize the iteration.
As for the Strategy pattern, this would be useful if you need to implement the logic of the different configurations in different classes. But as long as you only want to use different paths, this is probably overkill.

Take advantage of JSON flexibility in Java components

I am just trying to find a way to be more flexible.
I have a java web-app that connects to a noSql db (couchbase). In order to map the stored jsons I have created a jar which contains all the java classes for all those jsons.
Rex json document
{
"age":15
}
Mapping the json structure to java class:
public class Dog{
private int age;
// getters+setters
}
The problem I am facing is:
Whenever I update the db json structure (because json is flexible) I have to update also the java classes -> recompile a new jar version of the classes (and update the web-app dependency to the new jar version).
A newly needed update for Rex json:
{
"dob":"1999/01/25",
"name":"Rex"
}
I need an update to the Dog class looking like this:
public class Dog{
private String dob;
private String name;
// getters+setters
}
How can I create the java classes to be flexibleand to not need a new recompilation of the classes jar?
My main objective is to not update/redeploy the web-apps connecting to noSql in case of an update of json structure.
Hoping this is not a dumb question, I thank you,
Georgian
You can use a Map<String, String> for storing these values
How can I create the java classes to be flexibleand to not need a new recompilation of the classes jar?
I assume that you need to read and write JSON using these classes ...
If so, you need to choose between:
a JSON <-> Java binding (like you are currently using) where you will need to generate new Java classes when your JSON structures change, OR
a JSON binding that binds JSON "objects" to a Map type, OR
something like the old "org.json" library where you load JSON into a JSONObject.
There is no way to get a statically typed API (like your Dog class) that automagically deals with changing JSON structures.

How can I convert a java bean to a properties file?

What libraries are available that can do something like
public class Person {
private Long id;
private Name;
private List<Long> associations;
// accessors
}
public class Name {
private String first;
private String last;
// accessors
}
into something like
id=1
associations=1,2,3,4,5
name.first=Franz
name.last=See
And If there's no library to do that, what's a good way to do it? :-)
I doubt there's a library for that since common way to serialize beans is into XML. You may write simple library yourself using Java Reflection API to get list of properties and extract their values. It would be more common solution than making custom toString() for any class you may need to serialize.
Well I think instead of using any external library you can do it yourself just add getters and setters in your javabeans and override to string method of it and then you can form the string as you want.Then only task remaining is to write that string into one file, thats it!!!!!
Well, you can go check how XMLEncoder extract field names and values from object, and try to rewrite it to output properties files. I think that, by replacing xml output by properties output, you can get a fairly good properties creator. Notice, as an added benefit, that the same goes for properties reading using an equivalent opf XMLDecoder.
Please check if JSON would solve this problem.
import net.sf.json.JSONObject;
public class YourJSONJavaExample
{
public static void main(String args[]){
JSONObject object=new JSONObject();
object.put("firstname","John");
object.put("age",new Integer(21));
object.put("lastname","smith");
System.out.println(object);
}
}

How to easily load a XML-based Config File into a Java Class?

I've got a simple java class that looks something like this:
public class Skin implements Serializable {
public String scoreFontName = "TahomaBold";
...
public int scoreFontHeight = 20;
...
public int blockSize = 16;
...
public int[] nextBlockX = {205, 205, 205, 205};
...
public String backgroundFile = "back.bmp";
...
}
I'd like to read this information from a simple XML file that looks something like this:
<xml>
<skin>
<scoreFontName>"Tahoma Bold"</scoreFontName>
...
<scoreFontHeight>20</scoreFontHeight>
...
<blockSize>16</blockSize>
...
<nextBlockX>
<0>205</0>
<1>205</1>
<2>205</2>
<3>205</3>
<nextBlockX>
....
<backgroundFile>"back.bmp"</backgroundFile>
...
<skin>
</xml>
Is there an easy way to inject the information from the xml file directly into the variable names rather than having to parse it manually? I don't mind using an external library.
Any help is appreciated.
XStream is really great library for just this.
http://x-stream.github.io/
You can set up aliases for your class and even custom data formats to make the XML file more readable.
Alternatives to the already mentioned solutions (XStream and Apache Commons Digester) would be Java's own JAXB for a comparable general approach, or solutions more tailored towards configuration like Apache Commons Configuration or Java's Preferences API.
I would actually recommend Apache Digester, since if your classes are beans, it will just handle reading the XML into them.
You can also use Spring - although it may be a bit of overkill for one class if its for a mobile game!
I've recently started using Simple http://simple.sourceforge.net/ for XML to object mapping. It uses annotations within the class similarly to method I use in C# and is nice and clean.
You can also break up the file into multiple classes and loading saving is a simple one liner.
In your case the Class structure would look like.
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
#Root (Name="skin")
public class Skin {
#Element(name="scoreFontName") // name param not needed if class field is the same as the xml (element) value
private String scoreFontName
#Element
private int scoreFontHeight
#Element
private int blockSize
#ElementArray
private int[] nextBlockX
#Element
private String backgroundFile
// getters
} 
Note one difference is that your array will be saved like this
<nextBlockX>
<int>205</int>
<int>205</int>
<int>205</int>
<int>205</int>
<nextBlockX>
But you you have the option of adding (entry="myName") to the annotation in which came the XML will be saved down like this
<nextBlockX>
<myName>205</myName>
<myName>205</myName>
<myName>205</myName>
<myName>205</myName>
<nextBlockX>
But the end result is the same once it's loaded into the array.
Use JAXB. It is included in the JDK starting with Java 1.6.

Categories