Need help in designing the class

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
LVL 14
sudhakar_koundinyaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sudhakar_koundinyaAuthor Commented:
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
sudhakar_koundinyaAuthor Commented:
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
Dejan PažinHead of SW DevelopmentCommented:

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

sudhakar_koundinyaAuthor Commented:
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
CEHJCommented:
>>System.setProperties(properties);

Careful there - that will replace all the properties as opposed to appending to them
0
Dejan PažinHead of SW DevelopmentCommented:

>>>  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
CEHJCommented:
templates = (templates == null)? transformerfactory.newTemplates(new StreamSource(xslFilename)) : templates;
0
sudhakar_koundinyaAuthor Commented:
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
CEHJCommented:
Use a static setter with the code i last posted
0
sudhakar_koundinyaAuthor Commented:
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
Dejan PažinHead of SW DevelopmentCommented:

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
RMaruszewskiCommented:
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
sudhakar_koundinyaAuthor Commented:
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
sudhakar_koundinyaAuthor Commented:
RMaruszewski,

Thanks for your code. That is what I get the idea from  dejanpazin's code
0
sudhakar_koundinyaAuthor Commented:
>>Careful there - that will replace all the properties as opposed to appending to them

Thanks CEHJ,

I will take care of that
0
sudhakar_koundinyaAuthor Commented:
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
sudhakar_koundinyaAuthor Commented:
Above code worked for me. No static methods other than Singleton instance

Thanks
Sudhakar
0
Dejan PažinHead of SW DevelopmentCommented:


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
sudhakar_koundinyaAuthor Commented:
Yeah,

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

Thanks Again,
Sudhakar
0
CEHJCommented:
8-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.