support multiple instances of views in eclipse e4 - java

In eclipse 3.x, we can able to open multiple instances of view part by providing different secondary id. How can i achieve the same behaviour in eclipse 4, I am not able to find any property of part which support this behaviour.
Other question is I am migrating 3.x application to 4.x using compat layer, i have imported 3.x views in application model and added them in perspectives using placeholders. My problem is if i open first instance of same view, it opens at appropriate partsashcontainer as defined in application model but after that if i open another instance of view, it opens in any area of the perspective instead of defined layout?
So how can i force eclipse 4 to open a view in one layout area if i am opening multiple instances of the view simultaneously?

The solution is as suggested by #greg-449, I have to create part using EpartService and then attach the part to partstack. As i am using comapt layer so it is not straight forward and have to write some dirty code to achieve that:
IEclipseContext serviceContext = E4Workbench
.getServiceContext();
final IEclipseContext appContext = (IEclipseContext) serviceContext
.getActiveChild();
EModelService modelService = appContext
.get(EModelService.class);
MApplication app = serviceContext.get(MApplication.class);
EPartService partService = serviceContext
.get(EPartService.class);
MPartStack stack = (MPartStack) modelService.find(
"partstack.2", app);
MPart part = modelService.createModelElement(MPart.class);
part.setElementId("viewID");
part.setContributionURI("bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityView");
part.setCloseable(true);
part.getTags().add(EPartService.REMOVE_ON_HIDE_TAG);
stack.getChildren().add(part); // Add part to stack
MPart viewPart = partService.showPart(part,
PartState.ACTIVATE); // Show part
ViewReference ref = ((WorkbenchPage) PlatformUI
.getWorkbench().getActiveWorkbenchWindow()
.getActivePage()).getViewReference(part);
IViewPart viewRef = ref.getView(true);
Using this we can open the view using E4 and get the instance of IViewpart to perform other operations of 3.X

Related

How do I exclude certain Vaadin views from authentication?

I want to make a couple of Vaadin (v22) views accessible without a login, i.e. make them publicly available.
I looked at this tutorial, which is probably outdated: https://vaadin.com/learn/tutorials/securing-your-app-with-spring-security
There it says, that all views not using the #Secured annotation are publicly accessible. In my case it is different. Nothing is accessible at all, unless anotated with #PermitAll then logged in users can access the page.
As ever so often, I found the answer while preparing the question.
The annotation to use is #AnonymousAllowed
Example:
#Route(value = "/welcome", layout = PublicLayout.class)
#RouteAlias(value = "", layout = PublicLayout.class)
#AnonymousAllowed
public class PublicWelcomePage extends Div {
// create your view here
}
Official Vaadin v22 docs

Use FindReplaceAction in custom view

In my view I have a StyledText on which I want to open the default eclipse find/replace-dialog (The one that appears in the editor on Ctlr+F).
Therefore I want to instantiate and run the FindReplaceAction but my problem is that this action needs a ResourceBundle as a parameter and I have no idea what this is used for and where I can get it from...
I wonder whether this is actually the way to accomplish this functionality or if there is a way to register my view (that implements IFindReplaceTarget) globally in eclipse to recieve the Ctrl+F shortcut for opening the dialog
You should be able to participate in the standard Find/Replace code by having your view respond to a request for the IFindReplaceTarget in the getAdapter method of your main ViewPart class and setting up the find and replace action.
The adapter is something like:
#SuppressWarnings("unchecked")
#Override
public <T> T getAdapter(Class<T> required) {
if (IFindReplaceTarget.class.equals(required)) {
return (T) ... your find replace target class
}
... other adapters
}
Note: Older versions of Eclipse don't use Generics for this method.
Set up the FindReplaceAction with something like:
ResourceBundle bundle = ResourceBundle.getBundle("my.package.Messages");
FindReplaceAction findReplaceAction = new FindReplaceAction(bundle, "find_replace_action_", this);
findReplaceAction.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE);
IActionBars actionBars = getViewSite().getActionBars();
actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(), findReplaceAction);
The resource bundle needs a Messages.properties file with contents like:
find_replace_action_label=&Find/Replace...
find_replace_action_tooltip=Find/Replace
find_replace_action_image=
find_replace_action_description=Find/Replace

java MVC application

i'm creating an application at the moment that i want to reuse the GUI so to make it easy to reuse and change the elements I've been using the MVC design pattern but im having a few issues with it the first issue is how to implement the actual design pattern as different examples implement it in different ways. this is the code i have in my main, does this look ok.
mainView theView = new mainView();
mainModel theModel = new mainModel();
mainController theController = new mainController(theView,theModel);
theView.setVisible(true);
The second problem i have was the example set up was the controller implemented a view in the by using the following code:
controller:
this.theView.addCalculateListener(new CalculateListener());
view:
public void addCalculateListener(ActionListener listenForCalcButton){
calculateButton.addActionListener(listenForCalcButton);
}
this seems to work fine but i have problems implementing listeners in the JMenu as there added within the constructor of the view so my plan was to create the JMenu in an external class where i can put all the menu items as global variables (to clear up code) which will allow me to add the listeners in this manner, is this an OK solution or am i way off.

Menu bar not displaying in eclipse e4 on restore state

I am creating an RCP application using Eclipse 4.4.1 with the Compatibility Layer (migration from 3.x to 4.x). I have defined menus in the application model. Menus are displaying properly when the application is launched for the first time, but restarting the application is hiding the menu bar completely and only showing the toolbar.
Why might no menus be displaying when the RCP Application is restored?
This sounds like this bug here that I just recently myself encountered:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=388808
Personally, the workaround in the bug report did not exactly work for me (it may for you however). What did work for me was based off of the final post here by Karl Puperze, (slightly modified):
https://www.eclipse.org/forums/index.php/t/446433/
public class ForceMainMenuProcessor
{
#Execute
public void execute(#Optional MApplication application, #Optional EModelService modelService)
{
MTrimmedWindow window = (MTrimmedWindow)
modelService.find("<id of your main trimmed window>", application);
if (window == null || window.getMainMenu() != null)
{ return; }
final MMenu mainMenu = modelService.createModelElement(MMenu.class);
mainMenu.setElementId("org.eclipse.ui.main.menu");
window.setMainMenu(mainMenu);
}
}
From that, the last steps were to make sure I defined (with no content) a menu in the main e4xmi file that had the org.eclipse.ui.main.menu id, then defined a fragment that contained the menu contents.
To the plugin.xml, added to the org.eclipse.e4.workbench.model extension point a fragment that pointed to the .e4xmi model fragment that was just created and set the 'apply' to always.
Finally, to the same extension point, added a processor and pointed it to the class above. beforefragment was true and apply was always.
The e4xmi files were still used to define the menu, but in code, because of the defined processor above, the menu is forced to appear regardless of whatever persistent state was saved in the workspace. I ended up with this solution after already splitting the menu into a separate model fragment, so I am not sure if that part of the solution is definitely required, but most certainly defining the processor is.

Accessing and using .jsf files from the database

What is the best way to enable my webapplication to use JSF files stored in the database?
I'd like to be able to dynamically (during runtime) create new JSF pages which will be made available without having to redeploy the application.
So in other words: I would like to store the bigger part of my JSF pages in the database and would like JSF to use the database as a datasource for getting JSF files.
I've thought long about a solution and found some possible ways. However, I haven't been able to implement either of them.
Whenever a new page has to be added/removed: manipulate the files in the classpath (e.g. remove or add a file to the .war file)
Extending the classpath of the webapplication so it will be able to get files from an at runtime defined location (i.e. /tmp or directly using a database connection)
Provide JSF with a way to find resources another way ( this doesn't seem possible? )
My environment:
Java SE 6
Jetty as servlet container
Mojarra as jsf implementation
Now, my question:
Is it possible for someone to let JSF find pages at a location other than the default classpath, preferably the database?
Any response is greatly appreciated!
1: Whenever a new page has to be added/removed: manipulate the files in the classpath (e.g. remove or add a file to the .war file)
This is definitely possible if the WAR is expanded. I am not sure about Jetty, but it works for me with Mojarra 2.x on Tomcat 7 and Glassfish 3. Just writing the file to the expanded WAR folder the usual Java IO way suffices.
File file = new File(servletContext.getRealPath("/foo.xhtml"));
if (!file.exists()) {
OutputStream output = new FileOutputStream(file);
try {
output.write(bytes); // Can be bytes from DB.
} finally {
output.close();
}
}
This needs to be executed before the FacesServlet kicks in. A Filter is a perfect place. See also this related answer:
How to create dynamic JSF form fields
2: Extending the classpath of the webapplication so it will be able to get files from an at runtime defined location (i.e. /tmp or directly using a database connection)
You can package Facelets files in a JAR file and put it in the classpath and provide a Facelets ResourceResolver which serves the files from the JAR on when no match is found in WAR. You can find complete code examples in the following answers:
how to share a jsf error page between multiple wars
How to create a modular JSF 2.0 application?
3: Provide JSF with a way to find resources another way ( this doesn't seem possible? )
You've plenty of play room in the custom ResourceResolver.
Nice question. BalusC's answer is - as always - complete and right.
However, if your point is to create an application where gui is built dynamically, there is a way that might serve you better (depending on what you really want to achieve).
JSF views are similar to Swing forms - they are just a bunch of JavaBeans(tm) glued together. The big difference is that when a field is bound to an EL expression, you do not use standard accessors, but rather a special method (setValueExpression).
This means you can build your GUI from objects (the concrete classes can be found in javax.faces.component.html) in a pure programmatic way and then use binding attribute to show it on page. Something like:
<h:form>
<h:panelGrid binding="#{formBuilder.component}"/>
</h:form>
And then in the managed formBuilder bean:
#PostConstruct
public void init() {
HtmlInputText hit = new HtmlInputText();
// properties are easy:
hol.setStyle("border: 2px solid red");
// binding is a bit harder:
hit.setValueExpression("value", expression("#{test.counter}", String.class));
HtmlOutcomeTargetLink hol = new HtmlOutcomeTargetLink();
hol.setValue("link leading to another view");
hol.setOutcome("whatever");
component = new UIPanel();
component.getChildren().add(hit);
component.getChildren().add(hol);
}
private ValueExpression expression(String s, Class c){
return FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createValueExpression(
FacesContext.getCurrentInstance().getELContext(),
s, c
);
}
The example above builds a static panel, but it would be possible to:
create an object model of your GUI
map the model to database (with hibernate or another orm)
write some kind of adapter or bridge to build JSF objects from your object model
make a managed bean that receives the form id, grabs the relevant form from database, builds a JSF panel out of it and presents it as a property, ready to be bound.
This way you could have just one static xhtml with a single tag and use it to present any number of dynamic forms.
As I said, this method could be better than just storing files, but not necessarily. If you just want to save yourself the hassle of redeployment, this is a huge overkill (then again, you do NOT need to redeploy JSF applications just to change forms). If on the other hand your goal is to have something like user-defined and edited forms, having a good object model and storing it in a proper way could be a good idea.
The bumps ahead would be:
navigation (perhaps a custom navigation handler would suffice?)
problems with generating plain html
possibly some problems with lifecycle of view scoped forms

Categories

Resources