Parsing mixed list with SimpleXML - java

Within the <Images> tag, this API call returns a mix of different types: fanart, boxart, banner, screenshot, clearlogo.
Using SimpleXML Framework, what is the best way to go about parsing those into separate Lists? I'd like a List<FanArt>, List<BoxArt>, List<Banner> etc. The examples on the site do not seem to cover this situation. I've fumbled about with a few different ideas, but I'm not even sure SimpleXML Framework can handle this in a straight forward way.
For example, the below throws this exception: org.simpleframework.xml.core.PersistenceException: Duplicate annotation of name 'Images' on field 'clearLogos'.....
#ElementList(name = "Images", entry = "clearlogo")
private List<ClearLogo> clearLogos;
#ElementList(name = "Images", entry = "boxart")
private List<BoxArt> boxart;

In case anyone comes across this and needs some sort of solution, I've done this for now to get it working. Does the job but it's not really what I was after.
#Root
public class Images {
#ElementListUnion({
#ElementList(entry = "fanart", type = FanArt.class, inline = true),
#ElementList(entry = "boxart", type = BoxArt.class, inline = true),
#ElementList(entry = "screenshot", type = ScreenShot.class, inline = true),
#ElementList(entry = "banner", type = Banner.class, inline = true),
#ElementList(entry = "clearlogo", type = ClearLogo.class, inline = true)
})
private List<Object> images;
private List<FanArt> fanarts;
private List<BoxArt> boxarts;
private List<ScreenShot> screenshots;
private List<Banner> banners;
private List<ClearLogo> clearlogos;
public List<FanArt> getFanarts() {
if (fanarts == null) {
fanarts = new ArrayList<FanArt>();
for (Object image : images) {
if (image instanceof FanArt) {
fanarts.add((FanArt) image);
}
}
}
return fanarts;
}
public List<BoxArt> getBoxarts() {
if (boxarts == null) {
boxarts = new ArrayList<BoxArt>();
for (Object image : images) {
if (image instanceof BoxArt) {
boxarts.add((BoxArt) boxarts);
}
}
}
return boxarts;
}
public List<ScreenShot> getScreenshots() {
if (screenshots == null) {
screenshots = new ArrayList<ScreenShot>();
for (Object image : images) {
if (image instanceof ScreenShot) {
screenshots.add((ScreenShot) image);
}
}
}
return screenshots;
}
public List<Banner> getBanners() {
if (banners == null) {
banners = new ArrayList<Banner>();
for (Object image : images) {
if (image instanceof Banner) {
banners.add((Banner) image);
}
}
}
return banners;
}
public List<ClearLogo> getClearLogos() {
if (clearlogos == null) {
clearlogos = new ArrayList<ClearLogo>();
for (Object image : images) {
if (image instanceof ClearLogo) {
clearlogos.add((ClearLogo) image);
}
}
}
return clearlogos;
}
}

Related

Jackson no suitable constructor found for android.graphics.Bitmap

I'm trying to serialize my Character object with the use of Jackson. The mapper.writeValue method invocation is successful it seems, but when I try to read the value with the use of mapper.readValue I get the following error message:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of android.graphics.Bitmap: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
at [Source: java.io.FileReader#9ab6557; line: 1, column: 199] (through reference chain: java.lang.Object[][0]->com.myproj.character.Character["compositeClothes"]->com.myproj.character.clothing.CompositeClothing["clothes"]->java.util.ArrayList[0]->com.myproj.character.clothing.concrete.Hat["bitmap"])
These are my classes:
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "#class")
#JsonSubTypes({
#JsonSubTypes.Type(value = Hat.class, name = "hat"),
#JsonSubTypes.Type(value = Necklace.class, name = "necklace"),
#JsonSubTypes.Type(value = Shirt.class, name = "shirt")
})
public interface Clothing {
int getCoolness();
int getrId();
Bitmap getBitmap();
}
My hat class:
public class Hat implements Clothing {
private int rId;
private int coolness;
private Bitmap bitmap;
#JsonCreator
public Hat(#JsonProperty("coolness") int coolness, #JsonProperty("bitmap") Bitmap bitmap) {
rId = R.id.hat_image;
this.coolness = coolness;
this.bitmap = bitmap;
}
public int getrId() {
return rId;
}
#Override
public int getCoolness() {
return coolness;
}
public Bitmap getBitmap() {
return bitmap;
}
}
My composite clothing class:
public class CompositeClothing implements Clothing, Iterable<Clothing> {
#JsonProperty("coolness")
private int coolness = 0;
private List<Clothing> clothes = new ArrayList<>();
public void add(Clothing clothing) {
clothes.add(clothing);
}
public void remove(Clothing clothing) {
clothes.remove(clothing);
}
public Clothing getChild(int index) {
if (index >= 0 && index < clothes.size()) {
return clothes.get(index);
} else {
return null;
}
}
#Override
public Iterator<Clothing> iterator() {
return clothes.iterator();
}
#Override
public int getCoolness() {
return coolness;
}
#Override
public int getrId() {
return 0;
}
#Override
public Bitmap getBitmap() {
return null;
}
}
And my character class:
public class Character implements Observable {
private static final transient Character instance = new Character();
#JsonProperty("compositeClothes")
private CompositeClothing clothes = new CompositeClothing();
#JsonProperty("compositeHeadFeatures")
private CompositeHeadFeature headFeatures = new CompositeHeadFeature();
private transient List<Observer> observers = new ArrayList<>();
#JsonProperty("skin")
private Skin skin;
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
public void setSkin(Skin skin) {
this.skin = skin;
notifyAllObservers();
}
public Skin.Color getSkinColor() {
return skin.getColor();
}
public Bitmap getSkinBitmap() {
return skin.getBitmap();
}
public boolean hasSkin() {
return skin != null;
}
public void addClothing(Clothing clothing) {
Clothing oldClothing = (Clothing) getSameTypeObjectAlreadyWorn(clothing);
if (oldClothing != null) {
clothes.remove(oldClothing);
}
clothes.add(clothing);
notifyAllObservers();
}
public CompositeClothing getClothes() {
return clothes;
}
private Object getSameTypeObjectAlreadyWorn(Object newClothing) {
Class<?> newClass = newClothing.getClass();
for (Object clothing : clothes) {
if (clothing.getClass().equals(newClass)) {
return clothing;
}
}
return null;
}
public void removeClothing(Clothing clothing) {
clothes.remove(clothing);
}
public void addHeadFeature(HeadFeature headFeature) {
HeadFeature oldHeadFeature = (HeadFeature) getSameTypeObjectAlreadyWorn(headFeature);
if (oldHeadFeature != null) {
headFeatures.remove(oldHeadFeature);
}
headFeatures.add(headFeature);
notifyAllObservers();
}
public void removeHeadFeature(HeadFeature headFeature) {
headFeatures.remove(headFeature);
}
public CompositeHeadFeature getHeadFeatures() {
return headFeatures;
}
public static Character getInstance() {
return instance;
}
}
The code that I'm using to persist and then read the data:
File charactersFile = new File(getFilesDir() + File.separator + "characters.ser");
ObjectMapper mapper = new ObjectMapper()
.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
try (FileWriter fileOut = new FileWriter(charactersFile, false)) {
List<Character> characters = Arrays.asList(character);
mapper.writeValue(fileOut, characters);
} catch (IOException e) {
e.printStackTrace();
}
Character[] characters = null;
try (FileReader fileIn = new FileReader(charactersFile)) {
characters = mapper.readValue(fileIn, Character[].class);
} catch (IOException e) {
e.printStackTrace();
}
Thanks!
If your bitmaps come from assets or resources, there is no point on saving the bitmaps to JSON. That would be a waste of CPU time and disk space. Instead, store a value in the JSON that will allow you to identify the asset or resource to display. However, bear in mind that resource IDs (e.g., R.drawable.foo) can vary between app releases, so that is not a good durable identifier for the image.
I have similar requirement in my app where I need to store drawable data in JSON. I solved it by storing only its string name. For example, if I have resource R.drawable.testBmp then I store it in JSON like :
{
...
"mydrawable" : "testBmp"
}
Then at run time, I will read it and convert is as drawable like following code:
JSONObject jsonObj;
...
String bmpName = jsonObj.getString("mydrawable");
int resId = context.getResources().getIdentifier(bmpName,
"drawable",
context.getPackageName());
Drawable bmp = ContextCompat.getDrawable(context,resId);

FilteredTree is not filtering any items

currently I'm developing at a big software project and I need some help.
I added a FilteredTree so display a tree I created myself.
Following code is used to initialize it:
PatternFilter patternFilter = new PatternFilter();
dataTree = new FilteredTree(comp1, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL, patternFilter, true);
dataTreeViewer = signalTree.getViewer();
dataTreeViewer.setContentProvider(getDataTreeContentProvider());
dataTreeViewer.setLabelProvider(getDataTreeLabelProvider());
dataTreeViewer.setInput(data);
The input is a tree represented by a single node, which has childs and so on.
If I fill in some words in the filter literally nothing happens. I can write weird stuff but still everything will be shown.
I will also add some code for my label provider. Maybe you see the mistake. This is driving me nuts because I'm wasting hours and hours for this little thing.
public String getText(Object element) {
if (element != null) {
// MatTreeNode
if (element instanceof MatTreeNode) {
MatTreeNode node = (MatTreeNode) element;
return node.getName();
}
// OtherData
if (element instanceof OtherData) {
OtherData data = (OtherData) element;
return data.getName();
}
}
return null;
}
In my code OtherData is a different named class. I'm not allowed to post this code due to copyright reasons.
I hope someone of you can help me.
Have a great weekend!
Best regards
LouBen3010
Complete ContentProvider:
public class RawdataTreeContentProvider extends TreeNodeContentProvider implements IContentProvider {
final static String[] EMPTY_ARRAY = {};
#Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
#Override
public Object[] getChildren(Object parentElement) {
// MatTreeNode
if (parentElement instanceof MatTreeNode) {
MatTreeNode parent = (MatTreeNode) parentElement;
LinkedList<MatTreeNode> children = parent.getChildren();
Iterator<MatTreeNode> iterator = children.iterator();
MatTreeNode[] res = new MatTreeNode[children.size()];
int i = 0;
while (iterator.hasNext()) {
MatTreeNode node = iterator.next();
res[i] = node;
i++;
}
return res;
}
// SimpleTreeNode
if (parentElement instanceof SimpleTreeNode) {
SimpleTreeNode treeNode = (SimpleTreeNode) parentElement;
return treeNode.getChildren().toArray();
}
return EMPTY_ARRAY;
}
#Override
public Object getParent(Object element) {
if (element instanceof MatTreeNode) {
return ((MatTreeNode) element).getParent();
}
if (element instanceof SimpleTreeNode) {
return ((SimpleTreeNode) element).getParent();
}
return null;
}
#Override
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
}
Complete LabelProvider:
public class RawdataTreeLabelProvider extends LabelProvider implements ILabelProvider {
private Map<ImageDescriptor, Image> imageCache = new HashMap<ImageDescriptor, Image>();
#Override
public String getText(Object element) {
if (element != null) {
// MatTreeNode
if (element instanceof MatTreeNode) {
MatTreeNode node = (MatTreeNode) element;
return node.getName();
}
// SimpleTreeNode
if (element instanceof SimpleTreeNode) {
SimpleTreeNode signal = (SimpleTreeNode) element;
return signal.getName();
}
}
return null;
}
#Override
public Image getImage(Object element) {
// SimpleTreeNode
if (element instanceof SimpleTreeNode) {
ImageDescriptor descriptor = null;
SimpleTreeNode treeNode = (SimpleTreeNode) element;
SignalData signalData = treeNode.getContent();
// Chose image by signal type
if (signalData.getType() == 0) {
// Input
descriptor = getImageDescriptor("login-16.png");
}
else if (signalData.getType() == 1) {
// Output
descriptor = getImageDescriptor("logout-16.png");
}
// Try to get the image from cache
Image image = (Image) imageCache.get(descriptor);
// If not in cache load the corresponding image
if (image == null) {
image = descriptor.createImage();
imageCache.put(descriptor, image);
}
return image;
}
else {
return super.getImage(element);
}
}
/*
* Custom methods
*/
public ImageDescriptor getImageDescriptor(String name) {
ClassLoader loader = getClass().getClassLoader();
URL url = loader.getResource(name);
return ImageDescriptor.createFromURL(url);
}
}

Why am I getting null as the destination?

When I have the program print out System.out.println(_spaces.get("classroom").toStringLong()); it spits back "classroom: a large lecture hall with a door that goes null to sidewalk." Why does it say a door that goes to null? I think I have to fix my _buildPortals method, but I'm not sure how.
public class ConfigLoader
{
private Ini _ini;
private HashMap<String, Space> _spaces = new HashMap<String, Space>();
private HashMap<String, Portal> _portals = new HashMap<String, Portal>();
private HashMap<String, Agent> _agents = new HashMap<String, Agent>();
public ConfigLoader(File iniFile)
{
_ini = new Ini(iniFile);
}
public Agent buildAll()
{
_buildSpaces();
_buildPortals();
_buildExits();
_buildDestinations();
System.out.println(_spaces.get("classroom").toStringLong());
_buildAgents();
//return _selectStartAgent();
return null;
}
private void _buildSpaces()
{
for(String spaceName : _ini.keys("spaces"))
{
String description = _ini.get("spaces", spaceName);
String image = _ini.get("images", "images");
Space spaceInstance = new Space(spaceName, description, null, image);
_spaces.put(spaceName, spaceInstance);
}
}
private void _buildPortals()
{
for(String portalName : _ini.keys("portals"))
{
String description = _ini.get("portal", portalName);
Portal portalInstance = new Portal(portalName, description, null);
_portals.put(portalName, portalInstance);
}
}
private void _buildExits()
{
for(String spaceName : _ini.keys("exits"))
{
String spaceExit = _ini.get("exits", spaceName);
Space space = _spaces.get(spaceName);
Portal exit = _portals.get(spaceExit);
space.setPortal(exit);
}
}
private void _buildDestinations()
{
for(String portalName : _ini.keys("destinations"))
{
String destination = _ini.get("destinations", portalName);
Space dest = _spaces.get(destination);
Portal portal = _portals.get(portalName);
if(dest == null)
{
System.out.println("Error");
System.exit(1);
}
else
{
portal.setDestination(dest);
}
}
}
private void _buildAgents()
{
for(String agentName : _ini.keys("agents"))
{
String agent = _ini.get("agents", agentName);
Space space = _spaces.get(agent);
if(space == null)
{
System.out.println("Error");
System.exit(1);
}
else
{
Agent a = new Agent(space, agentName);
_agents.put(agentName, a);
}
}
}
private Agent _selectStartAgent()
{
for(String agentName : _ini.keys("start"))
{
String agent = _ini.get("start", agentName);
Agent agentInstance = _agents.get(agent);
if(agent == null)
{
System.out.println("Error");
System.exit(1);
}
else
{
return agentInstance;
}
}
return null;
}
}
Following the other patterns in your code, maybe..
String description = _ini.get("portal", portalName);
needs to be
String description = _ini.get("portals", portalName);
If so, it's usually a good idea to extract something like this to a string constant.
private static final String PORTALS = "portals";
and use that in multiple places.
Your buildSpaces method's second line is wrong. You're getting the image associated with a certain space but you have two strings in your get call and that's not right.

How do I "register" a new Module Type in an IntelliJ Plugin?

I am a beginner when it comes to IntelliJ plugin development but i want my plugin to register a new Module Type in the "New Project" / "New Module" windows.
I already searched through the Documentation for plugin developers but wasn't able to find anything useful. I also looked at existing plugins like Kotlin and Scala which also add new Module types but I can't figure out how to get a finished ModuleType to show up in the dialogs mentioned above.
What do I have to change in the plugin.xml file? I already added extensions and created java classes for ModuleType, ModuleBuilder and the ModuleConfigurationExtensionProvider but that doesn't change anything.
I hope you can help me and thanks in advance.
This can be achieved through New Project Wizard feature of IntelliJ IDEA, by providing your Module / Project type implementation class of ModuleBuilder i.e by extending the intelliJ IDEA provided extension point for the same (com.intellij).
You need the below changes to make in your plugin.xml for making appear your new Module / Project type in New Project Wizard project /modules types list.
<extensions defaultExtensionNs="com.intellij">
<moduleBuilder builderClass="com.yourcompany.wizards.YourModuleBuilder"/>
</extensions>
Provide your ModuleBuilder class with package to buildlerClass attribute, thats enough.
Here is sample ModuleBuilder implementation:
public class AsposeJavaModuleBuilder extends ModuleBuilder implements SourcePathsBuilder {
private Project myProject;
ResourceBundle bundle = ResourceBundle.getBundle("Bundle");
#Override
public String getBuilderId() {
return getClass().getName();
}
#Override
public String getPresentableName() {
return "Aspose Application";
}
#Override
public String getDescription() {
return bundle.getString("AsposeWizardPanel.myMainPanel.description");
}
#Override
public Icon getBigIcon() {
return AsposeIcons.AsposeMedium;
}
#Override
public Icon getNodeIcon() {
return AsposeIcons.AsposeLogo;
}
#Override
public ModuleWizardStep[] createWizardSteps(#NotNull WizardContext wizardContext, #NotNull ModulesProvider modulesProvider) {
return new ModuleWizardStep[]{
new AsposeAPIsWizardStep(this, wizardContext),
};
}
#Override
public void setupRootModel(ModifiableRootModel rootModel) throws com.intellij.openapi.options.ConfigurationException {
setMyProject(rootModel.getProject());
final CompilerModuleExtension compilerModuleExtension = rootModel.getModuleExtension(CompilerModuleExtension.class);
compilerModuleExtension.setExcludeOutput(true);
if (myJdk != null) {
rootModel.setSdk(myJdk);
} else {
rootModel.inheritSdk();
}
ContentEntry contentEntry = doAddContentEntry(rootModel);
if (contentEntry != null) {
final List<Pair<String, String>> sourcePaths = getSourcePaths();
if (sourcePaths != null) {
for (final Pair<String, String> sourcePath : sourcePaths) {
String first = sourcePath.first;
new File(first).mkdirs();
final VirtualFile sourceRoot = LocalFileSystem.getInstance()
.refreshAndFindFileByPath(FileUtil.toSystemIndependentName(first));
if (sourceRoot != null) {
contentEntry.addSourceFolder(sourceRoot, false, sourcePath.second);
}
}
}
}
if (myCompilerOutputPath != null) {
// should set only absolute paths
String canonicalPath;
try {
canonicalPath = FileUtil.resolveShortWindowsName(myCompilerOutputPath);
} catch (IOException e) {
canonicalPath = myCompilerOutputPath;
}
compilerModuleExtension
.setCompilerOutputPath(VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(canonicalPath)));
} else {
compilerModuleExtension.inheritCompilerOutputPath(true);
}
LibraryTable libraryTable = rootModel.getModuleLibraryTable();
for (Pair<String, String> libInfo : myModuleLibraries) {
final String moduleLibraryPath = libInfo.first;
final String sourceLibraryPath = libInfo.second;
Library library = libraryTable.createLibrary();
Library.ModifiableModel modifiableModel = library.getModifiableModel();
modifiableModel.addRoot(getUrlByPath(moduleLibraryPath), OrderRootType.CLASSES);
if (sourceLibraryPath != null) {
modifiableModel.addRoot(getUrlByPath(sourceLibraryPath), OrderRootType.SOURCES);
}
modifiableModel.commit();
}
RunnableHelper.runWhenInitialized(getMyProject(), new Runnable() {
public void run() {
System.out.println("Hello I came here");
final LibraryTablesRegistrar libTablesRegistrar = LibraryTablesRegistrar.getInstance();
final LibraryTable libraryTable = libTablesRegistrar.getLibraryTable(getMyProject());
final LibraryTable.ModifiableModel libTableModel = libraryTable.getModifiableModel();
Library library = libTableModel.createLibrary(AsposeConstants.LIBRARY_NAME);
libTableModel.commit();
#NonNls final String path = getContentEntryPath() + File.separator + AsposeConstants.LIB_FOLDER;
new File(path).mkdirs();
for (AsposeJavaAPI api : AsposeProject.getApiList().values()) {
System.out.println("Hello I came here2");
if (api.is_selected()) {
try {
System.out.println("Hello I came here3");
AsposeAPIsManager.copyDirectory(AsposeAPIsManager.getLibaryDownloadPath() + api.get_name().toLowerCase(), path + File.separator + api.get_name());
} catch (IOException ex) {
ex.printStackTrace();
}
String[] children = new File(path + File.separator + api.get_name().toLowerCase() + File.separator).list();
for (String _child : children) {
String jarPath = "jar://" + path + File.separator + api.get_name() + File.separator + _child + "!/";
Library.ModifiableModel model = library.getModifiableModel();
model.addRoot(jarPath, OrderRootType.CLASSES);
model.commit();
}
}
}
Collection<Module> modules = ModuleUtil.getModulesOfType(getMyProject(), StdModuleTypes.JAVA);
Iterator itr = modules.iterator();
Module module = null;
while (itr.hasNext()) {
module = (Module) itr.next();
break;
}
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
final ModifiableRootModel moduleRootModel = moduleRootManager.getModifiableModel();
final Library lib = libraryTable.getLibraryByName(AsposeConstants.LIBRARY_NAME);
if (moduleRootModel.findLibraryOrderEntry(lib) == null) {
moduleRootModel.addLibraryEntry(lib);
}
moduleRootModel.commit();
}
});
}
#Override
public String getGroupName() {
return JavaModuleType.JAVA_GROUP;
}
public Project getMyProject() {
return myProject;
}
public void setMyProject(Project myProject) {
this.myProject = myProject;
}
#Nullable
public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) {
AsposeIntroWizardStep step = new AsposeIntroWizardStep();
Disposer.register(parentDisposable, step);
return step;
}
private String myCompilerOutputPath;
// Pair<Source Path, Package Prefix>
private List<Pair<String, String>> mySourcePaths;
// Pair<Library path, Source path>
private final List<Pair<String, String>> myModuleLibraries = new ArrayList<Pair<String, String>>();
public final void setCompilerOutputPath(String compilerOutputPath) {
myCompilerOutputPath = acceptParameter(compilerOutputPath);
}
public List<Pair<String, String>> getSourcePaths() {
if (mySourcePaths == null) {
final List<Pair<String, String>> paths = new ArrayList<Pair<String, String>>();
#NonNls final String path = getContentEntryPath() + File.separator + "src";
new File(path).mkdirs();
paths.add(Pair.create(path, ""));
return paths;
}
return mySourcePaths;
}
public void setSourcePaths(List<Pair<String, String>> sourcePaths) {
mySourcePaths = sourcePaths != null ? new ArrayList<Pair<String, String>>(sourcePaths) : null;
}
public void addSourcePath(Pair<String, String> sourcePathInfo) {
if (mySourcePaths == null) {
mySourcePaths = new ArrayList<Pair<String, String>>();
}
mySourcePaths.add(sourcePathInfo);
}
public ModuleType getModuleType() {
return StdModuleTypes.JAVA;
}
#Override
public boolean isSuitableSdkType(SdkTypeId sdkType) {
return sdkType instanceof JavaSdkType;
}
#Nullable
#Override
public ModuleWizardStep modifySettingsStep(#NotNull SettingsStep settingsStep) {
return StdModuleTypes.JAVA.modifySettingsStep(settingsStep, this);
}
private static String getUrlByPath(final String path) {
return VfsUtil.getUrlForLibraryRoot(new File(path));
}
public void addModuleLibrary(String moduleLibraryPath, String sourcePath) {
myModuleLibraries.add(Pair.create(moduleLibraryPath, sourcePath));
}
#Nullable
protected static String getPathForOutputPathStep() {
return null;
}
}
For complete source code reference for creating new Module / Project Types in IntelliJ IDEA, please see the source code of Aspose Project Wizard (an IntelliJ IDEA Plugin By Aspose pty Ltd)
Source codes can be downloaded from the following URL:
https://asposejetbrains.codeplex.com/

Mass Java code file modifying - Remove methods, annotations, etc

I got a bundle of code from an very old project, which they generated many redundancy methods and annotations.
Is there anyway that fast, to remove -method "doOldThing()"- from all classes in this package; remove all #AnnotationObsoluted in all class?
I know that we can use search and replace, but writing regex to delete those take a long time. I guess we could have someway to parse a Java file, then remove "doOldThings()" method, check if #AnnotationObsoluted there then remove. Any idea? Tks.
In case anyone interest, here is the code for small util that I wrote to clean up methods (by name) and import statement as well.
import com.googlecode.java2objc.main.Config;
import com.googlecode.java2objc.main.Main;
import japa.parser.ASTHelper;
import japa.parser.JavaParser;
import japa.parser.ParseException;
import japa.parser.ast.CompilationUnit;
import japa.parser.ast.ImportDeclaration;
import japa.parser.ast.body.*;
import japa.parser.ast.expr.AnnotationExpr;
import japa.parser.ast.type.ClassOrInterfaceType;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* User: lent
* Date: 10/01/2014
*/
public class CleanUpAndModelRegeneration
{
public static void main(String... args) throws IOException, ParseException
{
List<File> results =
listFilesForFolder(new File("\\LocationOfYourCode"), new ArrayList<File>());
List<String> javaFiles = new ArrayList<String>();
for (File codeFile : results)
{
// creates an input stream for the file to be parsed
FileInputStream in = new FileInputStream(codeFile);
CompilationUnit cu = null;
try
{
// parse the file
cu = JavaParser.parse(in);
removeMethod(cu, "toString");
removeMethod(cu, "append");
removeMethod(cu, "appendFields");
removeMethod(cu, "fromValue");
optimizeImport(cu);
cleanUpInterfaces("ToString", cu.getTypes());
cleanUpAnnotationForEnum(cu);
// prints the resulting compilation unit to default system output
System.out.println(cu.toString());
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
finally
{
in.close();
}
FileOutputStream fileOutputStream = new FileOutputStream(codeFile, false);
fileOutputStream.write(cu.toString().getBytes());
fileOutputStream.flush();
javaFiles.add(codeFile.toString());
}
try
{
Config config = new Config();
Main main = new Main(config, javaFiles);
main.execute();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void cleanUpAnnotationForEnum(CompilationUnit cu)
{
for (TypeDeclaration type : cu.getTypes())
{
if (type instanceof EnumDeclaration)
{
EnumDeclaration enumDeclaration = (EnumDeclaration) type;
if (enumDeclaration.getAnnotations() != null)
{
enumDeclaration.getAnnotations().clear();
}
for (BodyDeclaration member : enumDeclaration.getMembers())
{
List<AnnotationExpr> annotations = member.getAnnotations();
if (annotations != null)
{
annotations.clear();
}
}
for (EnumConstantDeclaration member : enumDeclaration.getEntries())
{
List<AnnotationExpr> annotations = member.getAnnotations();
if (annotations != null)
{
annotations.clear();
}
}
}
}
}
private static void cleanUpInterfaces(String interfaceName, List<? extends BodyDeclaration> types)
{
for (BodyDeclaration type : types)
{
cleanUpInterface(type, interfaceName);
if (type instanceof TypeDeclaration)
{
List<BodyDeclaration> members = ((TypeDeclaration) type).getMembers();
if (members == null)
{
continue;
}
for (BodyDeclaration body : members)
{
if (body instanceof ClassOrInterfaceDeclaration)
{
cleanUpInterface(body, interfaceName);
cleanUpInterfaces(interfaceName, ((ClassOrInterfaceDeclaration) body).getMembers());
}
}
}
}
}
private static void cleanUpInterface(BodyDeclaration typeDeclaration, String interfaceName)
{
if (typeDeclaration instanceof ClassOrInterfaceDeclaration)
{
List<ClassOrInterfaceType> interfaceTypes = ((ClassOrInterfaceDeclaration) typeDeclaration).getImplements();
if (interfaceTypes == null)
{
return;
}
List<ClassOrInterfaceType> toBeRemove = new ArrayList<ClassOrInterfaceType>();
for (ClassOrInterfaceType interfaceType : interfaceTypes)
{
if (interfaceType.toString().equals(interfaceName))
{
toBeRemove.add(interfaceType);
}
}
interfaceTypes.removeAll(toBeRemove);
}
}
private static void optimizeImport(CompilationUnit cu)
{
List<ImportDeclaration> toBeRemove = new ArrayList<ImportDeclaration>();
if (cu.getImports() == null)
{
return;
}
for (ImportDeclaration importDeclaration : cu.getImports())
{
String importPackageName = importDeclaration.getName().toString();
if (importPackageName.startsWith("java.io")
|| importPackageName.startsWith("javax.xml.datatype")
|| importPackageName.startsWith("java.util")
|| importPackageName.startsWith("java.math")
|| importPackageName.startsWith("java.text"))
{
continue;
}
toBeRemove.add(importDeclaration);
}
cu.getImports().removeAll(toBeRemove);
}
public static List<File> listFilesForFolder(final File folder, List<File> result)
{
for (final File fileEntry : folder.listFiles())
{
if (fileEntry.isDirectory())
{
listFilesForFolder(fileEntry, result);
}
else
{
if (result == null)
{
result = new ArrayList<File>();
}
result.add(fileEntry);
}
}
return result;
}
private static void removeMethod(CompilationUnit cu, String methodName)
{
List<TypeDeclaration> types = cu.getTypes();
for (TypeDeclaration type : types)
{
List<BodyDeclaration> members = type.getMembers();
cleanUp(methodName, type, members);
if (type.getAnnotations() != null)
{
type.getAnnotations().clear();
}
type.setJavaDoc(null);
type.setComment(null);
}
}
private static void cleanUp(String methodName, BodyDeclaration type, List<BodyDeclaration> members)
{
List<BodyDeclaration> membersToRemove = new ArrayList<BodyDeclaration>();
for (BodyDeclaration member : members)
{
try
{
member.setJavaDoc(null);
member.setComment(null);
if (member.getAnnotations() != null)
{
member.getAnnotations().clear();
}
if (member instanceof MethodDeclaration && methodName.equals(((MethodDeclaration) member).getName()))
{
membersToRemove.add(member);
}
if (member instanceof ClassOrInterfaceDeclaration)
{
cleanUp(methodName, member, ((ClassOrInterfaceDeclaration) member).getMembers());
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
if (type instanceof TypeDeclaration)
{
((TypeDeclaration) type).getMembers().removeAll(membersToRemove);
}
else if (type instanceof ClassOrInterfaceDeclaration)
{
((ClassOrInterfaceDeclaration) type).getMembers().removeAll(membersToRemove);
}
else if (type instanceof EnumDeclaration)
{
((EnumDeclaration) type).getMembers().removeAll(membersToRemove);
}
}
private static void changeMethods(CompilationUnit cu)
{
List<TypeDeclaration> types = cu.getTypes();
for (TypeDeclaration type : types)
{
List<BodyDeclaration> members = type.getMembers();
for (BodyDeclaration member : members)
{
if (member instanceof MethodDeclaration)
{
MethodDeclaration method = (MethodDeclaration) member;
changeMethod(method);
}
}
}
}
private static void changeMethod(MethodDeclaration n)
{
// change the name of the method to upper case
n.setName(n.getName().toUpperCase());
// create the new parameter
Parameter newArg = ASTHelper.createParameter(ASTHelper.INT_TYPE, "value");
// add the parameter to the method
ASTHelper.addParameter(n, newArg);
}
}
If you erase the body of doOldThing():
doOldThing() {
}
And then inline the method, it should disappear wherever it is used. If instead you wanted to replace it with a call to doNewThing():
doOldThing() {
doNewThing();
}
and then inline.

Categories