I have a large monolithic webapplication that I whish to break apart into smaller modules. As a first step I'd like to change the package hierarchy which currently looks like:
- com.companyname.project
- dao
- bean
- booking // possibly containing more sub packages
- core
... etc etc (there are a bunch of others as well)
- service
- booking // possibly containing more sub packages
- core
... etc etc
- logic
- bean
- booking // possibly containing more sub packages
- core
... etc etc
- service
- booking
- core
... etc etc
- web
- bean // same substructure as above...
- service // same substructure as above...
- taglib // same substructure as above...
- util
I would like it if the package structure used for instance booking as the package name below com.companyname.project
Now I am wondering if there is a tool that could for instance use a simple regex to do the restructuring for me.
E.g.
com.companyname.project.dao.bean.booking
would become:
com.companyname.project.booking.dao.bean
and
com.companyname.project.dao.service.booking
would become:
com.companyname.project.booking.dao.service
I could use Eclipse and drag and drop the packages, but I am looking for something that could do this with a minimal of my involvment, since it will be very repetetive.
You can use any of the Java IDE with refactoring compatibilities:
IntelliJ IDEA (The best refactoring support). It has open source community edition and closed source ultimate edition.
Eclipse (open source)
NetBeans (open source)
I don't recommend you using regexp search/replace since it is error prone.
Why not use Java itself? I believe in your current scenario, you could easily write a small Java program to do the exact refactorings you're talking about and ensure that nothing is missed along the way.
You could write a method that takes "pre" (i.e. "com.companyname.project.dao.bean.booking") and "post" (i.e. "com.companyname.project.booking.dao.bean") params and copies the "pre" structure appropriately into the "post" structure.
In this program, I envision a main method and a "convertPackage(pre,post)" method. You could then have an array of your "pre" and "post" structures and loop through converting them over to the new. It would be best to do this copying into some sort of temp directory and not muck with the original as an added safety measure.
Maybe my thinking is too simple on this, but I could see a program built to do this refactoring in 1/2 a day or less.
You'll get the added benefit of knowing exactly what is changing rather than the insecurity that comes with these automated tools that may do it right for you or may not...
Related
I am facing a problem and I am kind of desesperate :
I am trying to transform a constraint OCL into a C# program. To do so, I define my ocl constraints in a CompleteOCL document, and I save it as Abstract Syntax : POC.ocl.oclas. Then I use Acceleo with the Pivot Meta-model ('http://www.eclipse.org/ocl/2015/Pivot').
However, common OCL operations (such as 'size') are defined in another model : the Library. So when I try to recover operations used on my OCL model, nothing happened, I can only recover the operation I defined in my ocl document.
When I opened POC.ocl.oclas, I have these 2 models :
POC.ocl model + Library model.
I defined these generation :
[comment encoding = UTF-8 /]
[module generate('http://www.eclipse.org/ocl/2015/Pivot','http://www.eclipse.org/ocl/2015/Library')]
[template public generateElement(aModel : Model)]
[comment #main/]
[file (aModel.name + 'xx', false, 'UTF-8')]
yo
[/file]
[/template]
And it only generate one file : "POC.oclxx", not "Library.oclxx"
That lead us to this question :
Is it possible in Acceleo to make a reference to another model (than the main one) ?
And if it is, how to do that ?
ANNEXE :
The code I wrote :
[comment getCode() opération/]
[template public getCode(operationCallExp : pivot::OperationCallExp) post (trim())]
[operationCallExp.ownedSource.getCode()/]
[operationCallExp.referredOperation.name/][operationCallExp.ownedArguments -> getArguments()/]
[/template]
In theory, [operationCallExp.referredOperation.name/] gives me the name of the operation. In reality, it gives me nothing, except when I defined the operation (and thus when the operation doesn't come from the OCL Library)
Thank you in advance !
The zipped projet : Archive_OCL_Acceleo
The POC folder contains POC metamodel (POC.ecore), OCL constraint on this metamodel (POC.ocl) and the Pivot model associate (POC.ocl.oclas). Files generated by Acceleo are in the files folder
The POC_Acceleo forlder contains the Acceleo transformation (generate.mtl)
From the *.oclas file extension, I take it that you are using the/my Pivot-based Eclipse OCL Abstract Syntax.
My first attempt at Java code generation from OCL used Acceleo, but I abandoned this for various reasons, not least of which is that the step from OCL AS to Java code is far too big to perform in a single M2T step. While Java (and no doubt C#) is deceptively similar to OCL making a simple text template-driven translation attractive, that approach is doomed to support only a modest language subset. Real code generation needs real analyses such as Common Subexpression Elimination and these introduce a conflict between preserved source and rewritten source, if you rewrite the source.
The current Eclipse OCL to Java Generator (my third attempt) uses an intermediate CG model where rewrites happen. It is intended to be retargetable to C (or C# or ...). I have many plans for a higher level of auto-generation in my next (fourth) attempt with a further Java (or C or C# or ...) intermediate model to separate the 'trivial' textual language serialization from the non-trivial language concept synthesis.
If you are interested in a serious rather than simplified example tool for C# generation, I strongly recommend you look at the Eclipse OCL CG. If you want to work collaboratively to making it better and are happy to make you contributions available under the EPL, then perhaps we can arrange something.
Are you using the latest code? I recall fixing a couple of bugs recently regarding missing 'cosmetic' AS model content.
Consider this line of jsp code:
function clearCart(){
cartForm.action="cart_clear?method=clear";
cartForm.submit();
}
Clearly it's trying to call a method on the back end to clear the cart. My question is how does the service (Tomcat most likely, correct me if I'm wrong) which hosts this site that contains this snippet of code know how and where to find this method, how it "indexes" it with string values etc. In my java file, the clear method is defined as:
public String clear( )
{
this.request = ServletActionContext.getRequest();
this.session = this.request.getSession();
logger.info("Cart is clearing...");
Cart cart = ( Cart ) this.session.getAttribute(Constants.SESSION_CART );
cart.clear();
for( Long id : cart.getCartItems().keySet() )
{
Item it = cart.getCartItems().get(id);
System.out.println( it.getProduct().getName() + " " + it.getNumber()
);
}
return "cart";
}
By which module/what mechanism does Tomcat know how to locate precisely that method? By copycatting online tutorials and textbooks I know how to write these codes, but I want to get a bit closer to the bottom of it all, or at least something very basic.
Here's my educated (or not so much) guess: Since I'm basing my entire project on struts, hibernate and spring, I've inadvertently/invariably configured the build path and dependencies in such ways that when I hit the "compile" button, all the "associating" and "navigating" are done by these framework, in other words, as long as I correctly configured the project and got spring etc. "involved" (sorry I can't think of that technical jargon that's on the tip of my tongue), and as long as I inherit a class or implement an interface, when compiling, the compiler will expose these java methods to the jsp script - it's part the work done by compiler, part the work done by the people who composed spring framework. Or, using a really bad analogy, consider a C++ project whereby you use a 3rd party library which came in compiled binary form, all you have to do is to do the right inclusion (.h/.hpp file) and call the right function and you'll get the function during run time when calling those functions - note that this really is a really bad analogy.
Is that how it is done or am I overthinking it? For example it's all handled by Tomcat?
Sorry for all the verbosity. Things get lengthy when you need to express slightly more complicated and nuanced ideas. Also - please go deep and go low-level don't go too deep, by that I mean you are free to lecture on how hibernate and spring etc. work, how its code is being run on a server, but try not to touch the java virtue machine, byte code and C++ pointers etc. unless of course, it is helpful.
Thanks in advance!
Tomcat doesn't do much except obey the Servlet specification. Spring tells Tomcat that all requests to http://myserver.com/ should be directed to Spring's DispatcherServlet, which is the main entry point.
Then it's up to Spring to further direct those requests to the code that handles them. There are different strategies for mapping a specific URL to the code that handles the request, but it's not set in stone and you could easily create your own strategy that would allow you to use whatever kind of URLs you want. For a simple (and stupid) example you could have http://myserver.com/1 that would execute the first method in a single massive handler class, http://myserver.com/2 would execute the second, etc.
The example is with Spring, but it's the same general idea with other frameworks. You have a mapper that maps an URL to the handler code.
These days it's all hidden under layers of abstraction so you don't have to care about the specifics of the mapping and can develop quickly and concentrate on the business code.
I'm interested in an executed script allowing user input to modify the process and corresponding source.
What precedents exist to implement such a structure?
Yes, depending on what is meant.
Consider such projects as ObjectWeb ASM (see the the ASM 2.0 tutorial for a general rundown).
Trying to emit the-would-need-to-be-decompiled Java source code is another story: if this was the goal then perhaps the source should be edited, re-compiled, and somehow loaded in/over. (This is possible as well, consider tools like JRebel.)
Happy coding.
You should not be able to modify existing classes. But if you implement a ClassLoader then you can dynamically load classes from non-traditional sources: network, XML file, user input, random number generator, etc.
There are probably other, better ways.
Maybe the Java scripting API is what you're looking for:
http://docs.oracle.com/javase/6/docs/api/javax/script/package-summary.html
http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html
I wrote an app once that used reflection to allow tests to be driven by a text file. For instance, if you had a class like this:
class Tuner(String Channel) {
tune(){...
play(){...
stop(){...
}
You could execute methods via code like:
tuner=Channel 1
tune tuner
play tuner
stop tuner
It had some more capabilities (You could pass objects into other objects, etc), but mostly I used it to drive tests on a cable box where a full write/build/deploy in order to test took on the order of a half hour.
You could create a few reusable classes and tie them together with this test language to make some very complex and easy to create tests.
THAT is a DSL, not monkeying around with your loose-syntax language by eliminating parenthesis and adding underscores and dots in random locations to make it look like some strange semi-English.
I'm building an application where I have my default webpage as 'index.jsp' which consists of a list of <stripes:link...> tags, to link out to my various actionBeans (to their defaulthandlers).
As my application evolves and gathers more actionBeans I'm going back and adding in a new link to them : is there a way to automate this - considering that the stripes framework (I believe) iterates through all the actionBeans when it loads up - is there a way to ask the framework for this information ?
The ActionResolver interface has several methods you could use, including getActionBeanClasses()
StripesFilter.getConfiguration() lets you access the configuration object (and hence the ActionResolver) in a static way.
Here's how to do it:
StripesFilter.getConfiguration().getActionResolver().getActionBeanClasses()
I'm refactoring some Java code to be more decoupled by changing some static method calls to non-static calls, for example:
// Before:
DAO.doSomething(dataSource, arg1, ..., argN)
// After:
dao.doSomething(arg1, ..., argN)
My problem is that in a large project, it can be hard to find where static method calls are being made. Is there an easy way to do this, either from the command line or in Eclipse?
Such a tool would need to let me ignore "benign" static method calls such as these (either by not finding them in the first place, or by allowing them to be easily deleted from the search results):
String.valueOf(...)
Integer.parseInt(...)
MyClass.someBenignStaticMethod(...)
Some clarifications:
I'm not interested in finding method calls made via reflection
I don't know what static methods currently exist in this project, so it's not as simple as searching for their callers using Eclipse's "Open Call Hierarchy" command (Ctrl-Alt-H), although an easy way to search for non-private static methods would let me use this approach
I'm also interested in finding calls to static methods located outside my project, e.g. javax.mail.Transport#send
I'm looking for a free (as in beer) solution
Do you really need to search? Why not comment out the static method calls one by one? When you compile it then it will flush out the references.
I'd use grep (-R on Linux) to search for initial caps-dot-camel case-open (I don't use it enough to give you the full command line). And then grep -v to get rid of some of the rubbish.
Well, really what I'd do is refactor incrementally. Changes a method, and see what breaks (if nothing breaks, delete the code).
Theoretically you could search through the class files looking for invokestatic. The FindBugs infrastructure would probably help out here (there may be better starting points).
Some IDEs provide support for refactoring. You can refactor every static method one-by-one.
In Eclipse, you can view the call hierarchy to see all the callers of such method. To view the call hierarchy you can select the method name and press Command-Alt-H, or Right-Click on symbol and choose 'Open Call Hierarchy).
We have a product called nWire for Java which might just help. nWire analyzes your code and builds a database of your code components and associations. You can see a brief demo on our web site.
We plan to have reporting capabilities added in the future. In the mean while, if you have some basic experience with databases, you can tap into the nWire repository and, with a simple SQL query, get a list of all your static methods (you can also see the invocations there). nWire uses the H2 database engine which is open-source and free.
I can assist in accessing the database. Drop me a line to support [at] nwiresoftware.com.
I've written a small Java program that uses the excellent ASM library. It lets you exclude packages like java.lang, and produces output that looks like this:
+ java
+ io
- File
# createTempFile(java.lang.String, java.lang.String)
+ javax
+ imageio
- ImageIO
# read(java.io.InputStream)
# write(java.awt.image.RenderedImage, java.lang.String, java.io.File)
+ mail
- Transport
# send(javax.mail.Message)
+ internet
- InternetAddress
# parse(java.lang.String, boolean)
+ xml
+ parsers
- DocumentBuilderFactory
# newInstance()
I'd prefer something that's more easily built into my existing build process, which uses CheckStyle, but this is the best solution I've come up with so far.
A possible solution could be a custom CheckSyle or PMD or ... warning. Currently I have the same challenge and trying it with CheckStyle. It seems to be right easy to write such an extention.