I am currently into Eclipse plugin development. I am in the need of using IMarker for a custom builder. I am creating project marker through org.eclipse.core.resources.IMarker and I am using IMarker.PROBLEM for two different situations.
How to delete and refresh a particular IMarker without deleting all the iMarker in the project resource.
I tried delete() method in the IMarker implementation. But it is not helping me out. And I found only the method deleteMarkers() in the project that actually deletes all the markers that are available in the project resource.
iProject.deleteMarkers(IMarker.PROBLEM, true,
IProject.DEPTH_INFINITE);
iProject.refreshLocal(IProject.DEPTH_INFINITE, null);
Please help me through this, I want to delete only a particular IMarker at the specified situation. I could not delete individual markers. Are there any source or reference you can point me to ? Thanks.
Basically, you have either store or find your specific markers. You can look for a marker in a selected resource (not on a project, but the current resource):
IMarker[] problems = null;
int depth = IResource.DEPTH_INFINITE;
try {
problems = resource.findMarkers(IMarker.PROBLEM, true, depth);
} catch (CoreException e) {
// something went wrong
}
When you have the correct marker, you can 1) update it by setting its properties, or 2) delete it using IMarker.delete().
The code snippet used here comes from the Mark My Words tutorial.
Related
I am customizing ICN (IBM Content Navigator) 2.0.3 and my requirement is to restrict user to upload files over 10mb and only allowed files are .pdf or .docx.
I know I have to extend / customize the AddContentItemDialog but there is very less detail on exactly how to do it, or any video on it. I'd appreciate if someone could guide.
Thanks
I installed the development environment but I am not sure how to extend the AddContentItemDialog.
public void applicationInit(HttpServletRequest request,
PluginServiceCallbacks callbacks) throws Exception {
}
I want to also know how to roll out the changes to ICN.
This can be easily extended. I would suggest to read the ICN red book for the details on how to do it. But it is pretty standard code.
Regarding rollout the code to ICN, there are two ways:
- If you are using plugin: just replace the Jar file on the server location and restart WAS.
- If you are using EDS: you need to redeploy the web service and restart WAS.
Hope this helps.
thanks
Although there are many ways to do this, one way indeed is tot extend, or augment the AddContentItemDialog as you qouted. After looking at the (rather poor IBM documentation) i figured you could probably use the onAdd event/method
Dojo/Aspect#around allows you to do exactly that, example:
require(["dojo/aspect", "ecm/widget/dialog/AddContentItemDialog"], function(aspect, AddContentItemDialog) {
aspect.around(AddContentItemDialog.prototype, "onAdd", function advisor(original) {
return function around() {
var files = this.addContentItemGeneralPane.getFileInputFiles();
var containsInvalidFiles = dojo.some(files, function isInvalid(file) {
var fileName = file.name.toLowerCase();
var extensionOK = fileName.endsWith(".pdf") || fileName.endsWith(".docx");
var fileSizeOK = file.size <= 10 * 1024 * 1024;
return !(extensionOK && fileSizeOK);
});
if (containsInvalidFiles) {
alert("You can't add that :)");
}else{
original.apply(this, arguments);
}
}
});
});
Just make sure this code gets executed before the actual dialog is opened. The best way to achieve this, is by wrapping this code in a new plugin.
Now on creating/deploying plugins -> The easiest way is this wizard for Eclipse (see also a repackaged version for newer eclipse versions). Just create a new arbitrary plugin, and paste this javascript code in the generated .js file.
Additionally it might be good to note that you're only limiting "this specific dialog" to upload specific files. It would probably be a good idea to also create a requestFilter to limit all possible uses of the addContent api...
I'm currently developing an eclipse plugin. This plugin contains a project nature which depends on the javaScript nature of jsdt.
Now at a few details the JavaScripts that the projects of my nature can contain are somewhat special.
They can contain "compiler hints" which are basicly statements beginning with #
They can contain return statements outside of functions
But at this two points the standard validation of jsdt come in and marks them as errors (which is normally right). I already managed to get this errors filtered out in the properties of the JavaScript validator (manually).
My question is, how can i exclude these errors from the validation of jsdt automatically for the projects with my nature?
JSDT uses concrete syntax parser which generates syntax errors.
You can't disable this. Only semantics error or warnings can be configured.
However you can disable entire validation of JSDT.
Below solution will suppress errors ands warnings which are generated while we save some changes on java script files. (Auto Build, Build)
Open Properties Dialog of Your Project.
Choose Builders item.
Uncheck "JavaScript Validator". And Press OK button.
Remove current errors and warnings from Problems View
This solution can't eliminate error or warning annotations in editor while you edit. They will show up on editor temporarily only when you edit it.
After a lot of research, hours of deleting markers and debugging i finally managed to delete the errors i wanted. In a bad bad way of course but i've come to a point where i just wanted this to work no matter how it's done.
If you ever want to delete existing problems that had been created during the validation process of jsdt you need to do the following (and you must not ommit anything):
Create a class extending org.eclipse.wst.jsdt.core.compiler.ValidationParticipant
Override isActive(), buildStarting() and reconcile() methods.
So there are two things you basicly have to care about.
The actual problem markers that will be created or had already been created at the end of the validation process.
The Problems created by the validation process. They are of the type CategorizedProblem and can be obtained by the ReconcileContext object that is passed to the reconcile() method.
It seems to me that the CategorizedProblems will be translated to problem markers after the validation process.
So what you need to do is:
Delete all unwanted problem markers of all files in buildStarting (this removes problem markers from all files in your project that are about to be validated)
Iterate the CategorizedProblem objects of the ReconcileContext (getProblems())
Create a new Array containing only the CategorizedProblems you want to keep
Set this new Array to the ReconcileContext with putProblems()
Delete the unwanted markers again for that file (i don't know why this is needed, please don't ask, i don't care anymore :-/)
An example implementation of such a validationParticipant could look like this: (this one will filter out problems complaining about return statements outside of methods:
[...ommited imports ...]
public class MyValidationParticipant extends org.eclipse.wst.jsdt.core.compiler.ValidationParticipant{
#Override
public boolean isActive(IJavaScriptProject project) {
return true;
}
#Override
public void buildStarting(BuildContext[] files, boolean isBatch) {
super.buildStarting(files, isBatch);
for(BuildContext context : files){
IFile file = context.getFile();
deleteUnwantedMarkers(file);
}
}
#Override
public void reconcile(ReconcileContext context) {
IResource resource = context.getWorkingCopy().getResource();
CategorizedProblem[] newProblems = new CategorizedProblem[0];
ArrayList<CategorizedProblem> newProblemList = new ArrayList<CategorizedProblem>();
CategorizedProblem[] probs = context.getProblems("org.eclipse.wst.jsdt.core.problem");
if(probs != null){
for(CategorizedProblem p : probs){
if(!(p.getMessage().equals("Cannot return from outside a function or method."))){
newProblemList.add(p);
}
}
}
}
context.putProblems("org.eclipse.wst.jsdt.core.problem", newProblemList.toArray(newProblems));
deleteUnwantedMarkers(resource);
}
public static void deleteUnwantedMarkers(IResource resource){
if(resource.isSynchronized(IResource.DEPTH_INFINITE)){
try {
IMarker[] markers = resource.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
if(markers != null && markers.length > 0){
for(IMarker m : markers){
Object message = m.getAttribute(IMarker.MESSAGE);
if(message.equals("Cannot return from outside a function or method.")){
m.delete();
}
}
}
}catch (CoreException e) {
e.printStackTrace();
}
}
}
}
As i said, this is kind of a bad solution since the code relies on the String of the error message. There should be better ways to identify the problems you don't want to have.
Don't forget to add a proper extension in your plugin.xml for the ValidationParticipant.
I'm using a TransactionalEditingDomain to manage changes on my model. However, I have some problems in creating an empty model. I think that the problem is when I add the model to the model Resource (modelResource.getContents().add(model);), because it should be put within a transaction. Accordingly, I was trying to use the AddCommand to perform such operation, but I am not able to find a EStructuralFeature for the Resource's contents.
In other words, I would like to write something like:
Command cmd = AddCommand.create(editingDomain, modelResource, FEAT_CONTENTS, model);
commandStack.execute(cmd);
The problem is that I cannot find the FEAT_CONTENTS... does anybody have a suggestion?
I have found the "official" solution with using AddCommand on the Eclipse Forum of EMF:
Command cmd = new AddCommand(editingDomain, modelResource.getContents(), model);
commandStack.execute(cmd);
Since removing a root object is also non-trivial, the same approach can be used with RemoveCommand:
Command cmd = new RemoveCommand(editingDomain, modelResource.getContents(), model);
Finally, for completeness, you should also know that DeleteCommand (that also removes all references to the removed object) does not work on root objects at all.
I found a solution, but sincerely I do not like it:
commandStack.execute(new RecordingCommand(editingDomain) {
protected void doExecute() {
modelResource.getContents().add(model);
}
});
I want to get the path of current selected file in Eclipse workspace but my project is a simple view plug-in project.
I just want to display the name/path of the file selected as soon as user opens the view.
You get the current selection as mentioned by #Danail Nachev. See http://www.eclipse.org/articles/Article-WorkbenchSelections/article.html for information on working with the selection service.
Once you have the selection, the most common pattern is:
if (selection instanceof IStructuredSelection) {
IStructuredSelection ssel = (IStructuredSelection) selection;
Object obj = ssel.getFirstElement();
IFile file = (IFile) Platform.getAdapterManager().getAdapter(obj,
IFile.class);
if (file == null) {
if (obj instanceof IAdaptable) {
file = (IFile) ((IAdaptable) obj).getAdapter(IFile.class);
}
}
if (file != null) {
// do something
}
}
Edit:
Usually you get an InputStream from the IFile and process it that way. Using some FileSystemProviders or EFS implementations, there might not be a local path to the file.
PW
You can retrieve the current workbench selection using two methods with the following code:
through the Workbench SelectionService
getViewSite().getSelectionProvider().getSelection()
getViewSite().getWorkbenchWindow().getSelectionService()
You can find more information in this article.
Using the global workbench selection is the better approach, because it enables your view to get selection from everywhere, which is something the user might expect (I at least do). Also, almost all of the views in Eclipse (and I don't know exceptions to this rule) are using this approach.
If you absolutely must to tie your view to another view, then you can get all IWorkbenchPage iterate over them and search for the view by its ID and when you find the view, you call get its SelectionProvider to get the selection.
Only by reading this explanation, makes my hair go straight up. Considering that there might be multiple instances of the same view, you can end up with a selection from a random view. I'm not sure whether the user will make sense of how things work, unless you have some clear rules, which exactly view you need. It is up to you.
`
I want to use the default XML editor (org.eclipse.wst.xml.ui) of Eclipse in an RCP application. I need to read the DOM of the xml file currently open. The plugin doesn't offer any extension point, so I'm trying to access the internal classes. I am aware that the I should not access the internal classes, but I don't have another option.
My approach is to create a fragment and an extension point to be able to read data from the plugin. I'm trying not to recompile the plugin, that's why I thought that a fragment was necessary. I just want to load it and extract the data at runtime.
So, my question is: is there another way to access the classes of a plugin? if yes, how?
Any tutorial, doc page or useful link for any of the methods is welcome.
Since nobody answered my question and I found the answer after long searches, I will post the answer for others to use if they bump into this problem.
To access a plugin at runtime you must create and extension point and an extension attached to it into the plugin that you are trying to access.
Adding classes to a plugin using a fragment is not recommended if you want to access those classes from outside of the plugin.
So, the best solution for this is to get the plugin source from the CVS Repository and make the modifications directly into the source of the plugin. Add extension points, extensions and the code for functionality.
Tutorials:
Getting the plugin from the CVS Repository:
http://www.eclipse.org/webtools/community/tutorials/DevelopingWTP/DevelopingWTP.html
Creating extensions and extension points and accessing them:
http://www.vogella.de/articles/EclipseExtensionPoint/article.html
http://www.eclipsezone.com/eclipse/forums/t97608.rhtml
I ended up extending XMLMultiPageEditorPart like this:
public class MultiPageEditor extends XMLMultiPageEditorPart implements
IResourceChangeListener {
#Override
public void resourceChanged(IResourceChangeEvent event) {
// TODO Auto-generated method stub
setActivePage(3);
}
public Document getDOM() {
int activePageIndex = getActivePage();
setActivePage(1);
StructuredTextEditor fTextEditor = (StructuredTextEditor) getSelectedPage();
IDocument document = fTextEditor.getDocumentProvider().getDocument(
fTextEditor.getEditorInput());
IStructuredModel model = StructuredModelManager.getModelManager()
.getExistingModelForRead(document);
Document modelDocument = null;
try {
if (model instanceof IDOMModel) {
// cast the structured model to a DOM Model
modelDocument = (Document) (((IDOMModel) model).getDocument());
}
} finally {
if (model != null) {
model.releaseFromRead();
}
}
setActivePage(activePageIndex);
return modelDocument;
}
}
This is not a clean implementation, but it gets the job done.