can this be considered duplicate code? - java

This is my first post here, recently i have been working with JSF2.0 with primefaces. we have this requirement to export PDF in our application. initially we used primefaces default dataexporter tag. but the format was simply terrible. so, i used itext to generate PDF. we have like upto 15 datatables in our app, and all of them require PDF exporting. i have created a method called generatePDF which creates the PDF using Itext for all the tables.
Interface PDFI {
public void setColNames();
public void setColValues();
public void setContentHeader();
}
Class DataEx {
public void generatePDF(ActionEvent event) {
// generate pdf...
}
}
consider i have a Datatable A in the view
Datatable A ...
bean behind this datatable..
Class BeanA implements PDFI {
//implemented methods
}
}
Class BeanB implements PDFI {
//implemented methods
}
and behind another datatable B, i do the same thing as above ..
so, my question here is, is this considered duplicate code ?? and also, is this the efficient way to do this.
any help is appreciated.
thanks ina dvance

Rule of thumb that I use before re-factoring duplicate code- when part of the code in one place have a bug- are you need to change the other one to? cause you probably will forget
in your case, it's look like you have duplicate code block. I'll consider add the require parameters to generatePDF so it'll do all work in one place.

Related

Ignore all checkstyle warnings for deprecated classes and methods

Can I somehow ignore any warning for deprecated class?
For example:
I had following warnings AvoidEscapedUnicodeCharacters, NonEmptyAtclauseDescription for deprecated class.
How to ignore all of them?
Checkstyle allows you to write your own custom filters. You can use SuppressWarningsFilter as a basis, because this filter is filtering based on annotations as well. You'd just need to change the annotation that you're looking for.
public class SuppressWarningsFilter
extends AutomaticBean
implements Filter {
#Override
protected void finishLocalSetup() {
// No code by default
}
#Override
public boolean accept(AuditEvent event) {
return !SuppressWarningsHolder.isSuppressed(event);
}
}
Pretty simple, but all of the logic is in SuppressWarningsHolder. That code is a few hundred lines, but you should be able to copy and paste a lot of it, and probably remove a large chuck as well.
I've implemented this: https://github.com/michaelboyles/checkstyle-annotation-filter. I'll make it available via the central repository at some point.
You just need to add the line below:
#SuppressWarnings("deprecation")
It will ignore all deprecated methods in your code.
I hope this will help.

using CayenneRuntime in webapplication without web.xml

I have a Wicket application and I'm trying to implement separate configuration that can be changed remotely. That's the end goal, anyway.
What I'm trying to do is set up Cayenne to work by starting it manually, rather than using the web.xml file. I have tried a bunch of different things, but I'm not sure I fully understand how the context is applied to all threads.
I have tried creating a ServerRuntime in my Application class. I've also tried on my custom BasePage class that each page uses. I can get it to kind of work by doing the following on the BasePage, but it is inconsistent:
public class BasePage ....
public static ServerRuntime runtime = new ServerRuntime("cayenne-config.xml");//This is in my BasePage class, but I've also tried this in the Application class
#Override
protected void init() {
BaseContext.bindThreadObjectContext(Application.runtime.getContext());//This is in my BasePage class
}
Like I said, that kind of works, but it isn't consistent. I keep getting errors on
BaseContext.getThreadObjectContext();
Error is this:
java.lang.IllegalStateException: Current thread has no bound ObjectContext.
I can't seem to find much information on this. I tried doing stuff like this, and accessing the runtime using these as well, but nothing is working consistently.
WebUtil.setCayenneRuntime(this.getServletContext(), runtime);
BaseContext.bindThreadObjectContext(WebUtil.getCayenneRuntime(((Application)getApplication()).getServletContext()).getContext());
Any help would be greatly appreciated.
I figured out a way to do this on my own.
I'm extending CayenneFilter and overriding the init method.
In there I copied nearly their exact code. I will be able to check for any config here and load the proper xml file. This obviously isn't the ironed out solution, but is definitely a step forward, and could be the way I end up doing this.
Either way, here's what I have tested to be working.
#WebFilter(filterName = "cayenne-config", displayName = "cayenne-config", urlPatterns = {"/*"})
public class TestFilter extends CayenneFilter
{
#Override
public void init(FilterConfig config) throws ServletException
{
this.checkAlreadyConfigured(config.getServletContext());
this.servletContext = config.getServletContext();
WebConfiguration configAdapter = new WebConfiguration(config);
Collection modules = configAdapter.createModules(new Module[]{new WebModule()});
ServerRuntime runtime = new ServerRuntime("cayenne-test.xml", (Module[])modules.toArray(new Module[modules.size()]));
WebUtil.setCayenneRuntime(config.getServletContext(), runtime);
}
}
I don't think the annotation is needed (I am specifying it all in the web.xml file), but I thought I would leave it here so you could see that it is changing.
If I could find a way to change the config (FilterConfig) values (the init parameters), then I could just change that to the name of the xml file I want to use and not override this entire method. I couldn't figure out how to do that, but I'll look further later.
If anyone has another better answer, I would love to hear it.

Importing a file with different layouts to a database in Java

I need to import a text file, with values separated by pipes ( | ), into a database using Java and Hibernate. The text file is generated elsewhere, and has the following layout:
example-file.txt
|0150|A|B|C|
|0150|X|Y|Z|
|0190|1|2|
|0200|9|8|7|H|F|E|
Each line corresponds to a record.
The first value (i.e 0150, 0190, 0200) is the type of info it holds (to which table it should be stored).
The rest are the values to be stored in that table.
So far, I've been able to read the lines, find to which Object the record corresponds to - using a Factory pattern - separating the values into a String[] array and calling a method createInstance(String[] fields) to create the object and store it into the database - using a Template pattern:
ImportServiceInterface
public interface ImportServiceInterface {
public void createInstance(String[] fields);
}
AbstractImportService
public abstract class AbstractImportService implements ImportServiceInterface {
public static ImportServiceInterface getImportService(String line) {
// returns the correct subclass
}
public void import() {
createInstance(splitFields());
}
public String[] splitFields(String line) {
// splits the line
}
}
So I have 3 separate services, each implementing their own version of createInstance(String[] fields):
ImportExampleTypeService
public ImportExampleTypeService implements AbstractImportService {
public void createInstance(String[] fields) {
ExampleModel myExample = new myExampleModel(); // mapped with Hibernate
// find which object members corresponds to the fields
// call the DAO to store the object
}
}
My problem is that the user will be able to specify his own layout: to which fields the values correspond to, size and position.
I thought about creating a table to store the layouts, then matching the names of the attributes using Reflection.
But I must be missing something, perhaps there's an easier way to do this?
SuperCSV supports custom delimiters and population of java objects via reflection, so I think it would do most of your work for you in this case.
Furthermore, it supports the concept of a header row as the first line in the file which then defines which fields those columns are mapped to in the java object, or you can just customize the column mappings manually.
Thank you #increment1 and #Templar for your answers!
The requirements have changed. The system has to be able to import both the above format (which will not be user-defined) and a user-defined, CSV-like, flat file, with a single type of record per file. It makes my life easier. I have been looking at different flat-file parsing libraries, and I'm posting it here in case anyone stumbles upon the same problem:
jflat: simple to use, extensible and customizable framework. Probably the best choice for most.
BeanIO: a flat-file marshaller/unmarshaller that uses xml files to figure out how to parse the file. Supports many formats, more than one type of record per file etc.
FFP: Flat File Parsing. Also supports absolute and relative definitions, using POJOs instead of xml files. I would have chosen this one, but it seems to be dead?
Flatworm: very similar to BeanIO. It appears it has inspired BeanIO, and there is not much activity on Flatworm either...
I have chosen BeanIO, because its flexibility suits my project better. So here's what I am going to do:
1) Keep my design, implementing my createInstance() method as needed;
2) Use a different implementation using BeanIO for the user-defined files;
3) Use a Facade to call the parser I need:
FacadeInterface
public interface ImportFacadeInterface {
public void importFile();
}
ImportDefaultLayoutFacadeImpl
public class ImportDefaultLayoutFacadeImpl implements ImportFacadeInterface {
public void importFile() {
// use the ImportServiceInterface
}
}
ImportUserDefinedLayoutFacadeImpl
public class ImportUserDefinedLayoutFacadeImpl implements ImportFacadeInterface {
public void importFile() {
// use BeanIO
}
}
My approch to store the possible record structures would be a Map with |0150| as Key and |A|B|C| as Value. This could be an approch to parse a line.
String line = ...;
String structure = map.get(line.substring(1, 4));
// Now you have the line structure and can parse it into your own format.

In Xwork, Can't -validation.xml be placed somewhere else than in the same package as the corresponding Action class

I'm working on service side POJO validation using xwork.
I am having an action, say ValidationAction.java, and I have a corresponding xml file named
ValidationAction-validation.xml, which has validation rules on fields.
As per the specification and the documentation I could find, I understand that this xml file should be kept in the same package as the ValidationAction.java file.
However, since I do have many java files to go through validation, and hence many corresponding xml files, I don't want to put them together in the same package.
I want to have a different folder/package for the xml files.
Is there any way out for this?
Thanks and regards.
You are putting them in the same pacage because that's how xwork validators work. What you can do, if you don't want to do all this, is implement the Validatable interface: define a custom validate() method on your action which will be called before the Action will be executed.
Example:
public void validate() {
if (todoManager.getTodo(id) == null) {
String error = getText("todo.err.notFound");
addActionError(error);
}
}

Highlight field in source code pane of Findbugs UI

I'm using a class that extends BytecodeScanningDetector to check for some problematic fields in a class.
After detecting whether the field is problematic, I add it to the bug report like below:
Once I run findbugs, it identifies the bug, lists it in the left pane, but does not highlight the corresponding source line.
Any hints/help on this will be very appreciated.
public void visit(Field f) {
if (isProblematic(getXField())) {
bugReporter.reportBug(new BugInstance(this,
tBugType,
HIGH_PRIORITY)
.addClass(currentClass) //from visit(JavaClass)
.addField(this));
}
}
public void visit(JavaClass someObj) {
currentClass = someObj.getClassName();
}
P.S. I tried posting this on the findbugs list but... no joy.
Unfortunately the java class file format does not associate line numbers with fields. The 'Line number table' attribute is an attribute of methods only. And so you can't do what you want to do.

Categories

Resources