?
Solved

Need help in designing the class

Posted on 2004-11-26
20
Medium Priority
?
257 Views
Last Modified: 2010-03-31
Hello  All,

I am creating a class in which  I made constuctor as a private (I want to avoid explicit creation of class instance here) and I created the methods as static methods.  All static methods uses below code snippet. And I want to avoid the below code execution for each call of method. The reason is transformer object can perform all operations once it's instance is created. There is no need to create new transformer for each method call.


try {
      properties.put(key, value);
      System.setProperties(properties);
      templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
      transformer = templates.newTransformer();
    }
    catch (Exception ex) {
    }



Hence I planned to put above code snippet in static block. But the problem is I wanted to create the StreamSource object for the xsl file and this argument comes from my static method as below. This  xsl file is same through out the program execution but the name will come from some other dynamic object at start of program execution.

  public static OutputStream transform(String inFilename, String xslFilename)
{
// some code here
}

So it is not possible to create the templates object  if I follow this model.
>>      templates = transformerfactory.newTemplates(new StreamSource(xslFilename));

But I want to avoid the multiple instance creation of templates object here, and also i do not want to use conditional statements here. Sso what changes  I need to do here??

Thanks,
Sudhakar Chavali
0
Comment
Question by:sudhakar_koundinya
  • 11
  • 4
  • 4
  • +1
20 Comments
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12679826
Hmm,

I got some idea


public static void SetXSL(String xslFilename)
{
    templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
      transformer = templates.newTransformer();
}

public static void transform(InputStream stream)
{
         transformer.transform(new StreamSource(stream), new StreamResult(out));
}


is this OK??

0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12679838
I think it is better option as per current situation.

I will wait for some time for new Ideas. Otherwise, I will close the question


Thanks
Sudhakar
0
 
LVL 17

Accepted Solution

by:
Dejan Pažin earned 720 total points
ID: 12679875

I would rather implement this as a Singelton pattern. That way you wouldnt need static methods, and also you would call your private constructor only once, and you could execute the code you need executed only once inside the constructor.

Take a look at the Singelton pattern here (its fairly simple):

http://www.javacoffeebreak.com/articles/designpatterns/
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12679970
dejanpazin,

thanks for ur response.
I know singleton model. But in my case if I choose singleton model,

How will you avoid creation of multiple instances of following tow objects??

 templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
      transformer = templates.newTransformer();

Thanks
sudhakar

0
 
LVL 86

Assisted Solution

by:CEHJ
CEHJ earned 140 total points
ID: 12680025
>>System.setProperties(properties);

Careful there - that will replace all the properties as opposed to appending to them
0
 
LVL 17

Assisted Solution

by:Dejan Pažin
Dejan Pažin earned 720 total points
ID: 12680027

>>>  How will you avoid creation of multiple instances of following tow objects??
>>>  templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
>>>      transformer = templates.newTransformer();

By putting these calls in constructor, you will assure that they will be executed only once, since it is a Singelton. Here is an example, lets say your class is called SingleObject:

public class SingleObject
{
   private static SingleObject singleObject;

   private SingleObject()
   {
     //// here is where you execute the methods that should only be called once:
     /////
      templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
      transformer = templates.newTransformer();
     //////
   }

   public static SingleObject getInstance()
   {
      if (singleObject == null)
      {
         singleObject = new SingleObject();
      }
      return singleObject;
   }

}
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12680035
templates = (templates == null)? transformerfactory.newTemplates(new StreamSource(xslFilename)) : templates;
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12680040
CODE
{
  private SingleObject()
   {
     //// here is where you execute the methods that should only be called once:
     /////
      templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
      transformer = templates.newTransformer();
     //////
   }
}
/CODE

But from where we shoud get the xslFileName.

Although, this  xsl file is same through out the program execution, but the name will come from some other dynamic object at start of program execution.

0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12680063
Use a static setter with the code i last posted
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12680088
That is what I have in mind as I metioned in my second comment

  static String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
  static Properties properties = System.getProperties();
  static Transformer transformer = null;
  static TransformerFactory transformerfactory = TransformerFactory.newInstance();
  static String xslFilename = "";
  static Templates templates = null;
    static {
    try {
      properties.put(key, value);
      System.setProperties(properties);

    }
    catch (Exception ex) {
    }

  }


  public static OutputStream transform(InputStream xmlStream, OutputStream out) {
    try {
      transformer.transform(new StreamSource(xmlStream), new StreamResult(out));
    }
    catch (Exception ex) {

    }
    return out;
  }

  public static void setXSLFile(String file) {
    xslFilename = file;
    try {
      templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
      transformer = templates.newTransformer();
    }
    catch (Exception ex) {

    }
  }


And in calling

Class.setXSLFile(Some XSL File);

while (program is still executing)
Class.transform(somexmlstream, somebufferstream);
0
 
LVL 17

Assisted Solution

by:Dejan Pažin
Dejan Pažin earned 720 total points
ID: 12680096

You can use plain setter for xslFilename, since you dont use static methods in my solution. So:

/// Method in SingleObject class
public setXslFileName(String xslFilename)
{
   this.xslFilename = xslFilename;
}


// And call to that method outside at start of the program:

SingleObject.getInstance().setXslFileName("yourXslFilename.xsl");
0
 
LVL 3

Assisted Solution

by:RMaruszewski
RMaruszewski earned 140 total points
ID: 12680105
SingleObject myObject = SingleObject.getInstance(xslFilename);

public SingleObject
{
  private static SingleObject m_singleObject = null;

  private SingleObject(String xslFilename)
  {
    m_templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
    m_transformer = templates.newTransformer();
  }

  public static SingleObject getInstance(String xslFilename)
  {
    if (singleObject == null)
         singleObject = new SingleObject(xlsFilename);

    return singleObject;
  }

  /* It will return null, is m_singleObject is not inited with xslFilename */
  public static SingleObject getInstance()
  {
    return singleObject;
  }
}
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12680144
dejanpazin ,

Cool, I got the Idea, from your comments

class Singleton
{
      Singleton singleton=null;
      private Singleton()
      {
      }
      public SingleTon getInstance()
      {
            if(singleton==null)
            {
                  singleton=new Singleton();
            }
            return singleton;
      }
      public Transformer getTransformer(String xslFileName)
      {
             String key = "javax.xml.transform.TransformerFactory";
             String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
             Properties properties = System.getProperties();
            Transformer transformer = null;
            TransformerFactory transformerfactory = TransformerFactory.newInstance();
            properties.put(key, value);
        System.setProperties(properties);
        templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
        transformer = templates.newTransformer();
            return transformer;
      }
}

class Test
{
       public static void main(String s[])
      {
             Transformer transformer=Singleton.getInstance().getTransformer("somexsl.xsl");
             for(int i=0;<100;i++)
            {
                   ByteArrayOutputStream out=new ByteArrayOutputStream();
                   transformer.transform(new StreamSource("c:/test/"+i+".xml"), new StreamResult(out));
                   //some other code goes here
                   out.close();
            }
      }
}


Is this what you are trying to say??
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12680154
RMaruszewski,

Thanks for your code. That is what I get the idea from  dejanpazin's code
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12680165
>>Careful there - that will replace all the properties as opposed to appending to them

Thanks CEHJ,

I will take care of that
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12680191
class Singleton {
  static Singleton singleton = null;
  private Singleton() {
  }

  public static Singleton getInstance() {
    if (singleton == null) {
      singleton = new Singleton();
    }
    return singleton;
  }

  public Transformer getTransformer(String xslFileName) {
    try {
      String key = "javax.xml.transform.TransformerFactory";
      String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
      Properties properties = System.getProperties();
      Transformer transformer = null;
      TransformerFactory transformerfactory = TransformerFactory.newInstance();
      properties.put(key, value);
      Templates templates = null;
      templates = transformerfactory.newTemplates(new StreamSource(xslFileName));
      transformer = templates.newTransformer();
      return transformer;
    }
    catch (Exception ex) {
      return null;
    }

  }
}

class Test {
  public static void main(String s[]) throws Exception {
    Transformer transformer = Singleton.getInstance().getTransformer(
        "somexsl.xsl");
    for (int i = 0; i < 100; i++) {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      transformer.transform(new StreamSource("c:/test/" + i + ".xml"),
                            new StreamResult(out));
      //some other code goes here
      out.close();
    }
  }
}
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12680197
Above code worked for me. No static methods other than Singleton instance

Thanks
Sudhakar
0
 
LVL 17

Expert Comment

by:Dejan Pažin
ID: 12680224


sudhakar_koundinya, I guess you could also do it like you are saying, but my solution is not exactly like that. I would make getTransformer method to only return transformer:

     public Transformer getTransformer()
     {
        return transformer;
     }

And have all the rest in the setTransfomer method. Of cource now transformer, has to be global variable.  But this way, you can achieve what you want from start: only call templates.newTransformer when you need to call it (like at the start of the program), and from there on just use the transformer.

     public void setTransformer(String xslFileName)
     {
           String key = "javax.xml.transform.TransformerFactory";
           String value = "org.apache.xalan.xsltc.trax.TransformerFactoryImpl";
           Properties properties = System.getProperties();
         
          TransformerFactory transformerfactory = TransformerFactory.newInstance();
          properties.put(key, value);
          System.setProperties(properties);
          templates = transformerfactory.newTemplates(new StreamSource(xslFilename));
          transformer = templates.newTransformer();
     }
0
 
LVL 14

Author Comment

by:sudhakar_koundinya
ID: 12680237
Yeah,

I understand that. I can handle rest of the things. No problems :)

Thanks Again,
Sudhakar
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 12680247
8-)
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
Suggested Courses
Course of the Month16 days, 11 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question