Open Perspective programmatically - eclipse-rcp

I am trying to provide a command/ handler to switch to a specific Perspective.
I came up with the following class:
public class OpenPerspectiveHandler {
private static final Logger logger = Logger.getLogger(OpenPerspectiveHandler.class);
#Inject
private MApplication application;
#Inject
private EModelService modelService;
#Inject
private EPartService partService;
private final String perspectiveId;
public OpenPerspectiveHandler(String perspectiveId) {
super();
this.perspectiveId = perspectiveId;
}
public void changePerspective(String perspectiveId) {
Optional<MPerspective> perspective = findPerspective();
if(perspective.isPresent()) {
partService.switchPerspective(perspective.get());
} else {
logger.debug("Perspective not found (" + perspectiveId + ")");
}
}
#Execute
public void execute() {
changePerspective(perspectiveId);
}
private Optional<MPerspective> findPerspective() {
MUIElement element = modelService.find(perspectiveId, application);
if(element instanceof MPerspective) {
return Optional.of((MPerspective)element);
} else {
logger.debug("Wrong type " + element);
}
return Optional.empty();
}
#Override
public String toString() {
return "OpenPerspectiveHandler [application=" + application + ", modelService=" + modelService + ", partService=" + partService + ", perspectiveId=" + perspectiveId + "]";
}
}
Interestingly, this works only once. A workaround is to cache MPerspective once it was found and not to use modelService.find(perspectiveId, application) again.
Why does it work only once? modelService.find(perspectiveId, application) returns null after the first execution.
EDIT:
Another approach (as suggested by greg-449) is the following:
public class OpenPerspectiveHandler {
private static final Logger logger = Logger.getLogger(OpenPerspectiveHandler.class);
private final String perspectiveId;
public OpenPerspectiveHandler(String perspectiveId) {
super();
this.perspectiveId = perspectiveId;
}
#Execute
public void changePerspective(MApplication application, EModelService modelService, EPartService partService) {
Optional<MPerspective> perspective = findPerspective(application, modelService);
if(perspective.isPresent()) {
partService.switchPerspective(perspective.get());
} else {
logger.debug("Perspective not found (" + perspectiveId + ")");
}
}
private Optional<MPerspective> findPerspective(MApplication application, EModelService modelService) {
MUIElement element = modelService.find(perspectiveId, application);
if(element instanceof MPerspective) {
return Optional.of((MPerspective)element);
} else {
logger.debug("Wrong type " + element);
}
return Optional.empty();
}
}
But this approach also changes the perspective only once. modelService.find(perspectiveId, application); returns null after the first execution.

The EPartService varies depending on the context that the handler runs in. In some cases you get the Application part service which only works if there is an active window.
You can get the part service for that window using something like:
MWindow window = (MWindow)modelService.find("top window id", application);
IEclipseContext windowContext = window.getContext();
EPartService windowPartService = windowContext.get(EPartService.class);

Related

mybatis interceptor throw Reflection exception affects cpu performence

I had implement a interceptor of myabtis. but we found a problem, execute interceptor lead to throw so many IllegalAccessException, it affects cpu performence
Shown below is where the problem is, why did not check access permision of feild befor executed code "field.get(target)".
public class GetFieldInvoker implements Invoker {
private final Field field;
public GetFieldInvoker(Field field) {
this.field = field;
}
#Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException {
try {
return field.get(target);
} catch (IllegalAccessException e) {
if (Reflector.canControlMemberAccessible()) {
field.setAccessible(true);
return field.get(target);
} else {
throw e;
}
}
}
#Override
public Class<?> getType() {
return field.getType();
}
}
the intercepor of mine:
#Intercepts({
#Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class})
})
public class SqlIdInterceptor implements Interceptor {
private static final int MAX_LEN = 256;
private final RoomboxLogger logger = RoomboxLogManager.getLogger();
#Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = realTarget(invocation.getTarget());
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
String originalSql = boundSql.getSql();
MappedStatement mappedStatement =
(MappedStatement) metaObject.getValue("delegate.mappedStatement");
String id = mappedStatement.getId();
if (id != null) {
int len = id.length();
if (len > MAX_LEN) {
logger.warn("too long id", "id", id, "len", len);
}
}
String newSQL = "# " + id + "\n" + originalSql;
metaObject.setValue("delegate.boundSql.sql", newSQL);
return invocation.proceed();
}
#SuppressWarnings("unchecked")
public static <T> T realTarget(Object target) {
if (Proxy.isProxyClass(target.getClass())) {
MetaObject metaObject = SystemMetaObject.forObject(target);
return realTarget(metaObject.getValue("h.target"));
}
return (T) target;
}
}
Flame Graph
enter image description here
enter image description here
I need help, how to avoid throw exceptions, is any other way to reslove this problem?
thanks.

Screenshots is not attached Allure + Cucumber + TestNg + EventListener

Using Cucumber EventListener, I am trying to capture the screenshots in Allure report, but screenshots is not attached in the report.
Below are my CustomEventListener Code:
public class CListener extends TestRunner implements EventListener {
#Override
public void setEventPublisher(EventPublisher eventPublisher) {
eventPublisher.registerHandlerFor(TestStepFinished.class, this::stepFinished);
}
private void stepFinished(TestStepFinished event) {
PickleStepTestStep steps = (PickleStepTestStep) event.getTestStep();
String stepName = steps.getStep().getText();
if (event.getResult().getStatus().toString().equalsIgnoreCase("PASSED")) {
takeScreenshot(webDriver, event.getResult().getStatus().toString(), stepName);
} else if (event.getResult().getStatus().toString().equalsIgnoreCase("FAILED")) {
takeScreenshot(webDriver, event.getResult().getStatus().toString(), stepName);
}
Allure.addAttachment(stepName, new ByteArrayInputStream(((TakesScreenshot) webDriver).getScreenshotAs(OutputType.BYTES)));
}
private void takeScreenshot(WebDriver driver, String filePath, String screenName) {
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File("Screenshots\\" + filePath + "\\" + screenName + ".png"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Runner Class:
#CucumberOptions(
features = {"classpath:Login.feature"},
plugin = {
"summary",
"pretty",
"io.qameta.allure.cucumber6jvm.AllureCucumber6Jvm","utilities.CListener"},
glue = {"steps"}
)
public class TestRunner extends AbstractTestNGCucumberTests {
public static WebDriver webDriver;
#BeforeSuite
public void setup() {
WebDriverManager.chromedriver().setup();
webDriver = new ChromeDriver();
webDriver.manage().window().maximize();
}
#AfterSuite
public void tearDown() {
if (webDriver != null) {
webDriver.quit();
System.out.println("hello: inside teardown");
}
}
}
Sample code implementation can be found here

Netbeans QuickSearch Result to Lookup

Well, I'd like to provide QuickSearch result inside application, and, of course, through the lookup.
Searching works well, but found result is not visible through global lookup.
Can someone help to overcome this issue ?
Here is th code for a quicksearch :
public class QSERSCompany implements SearchProvider {
#Override
public void evaluate(SearchRequest request, SearchResponse response) {
try {
for (Company k : queries.ERSQuery.allCompanies()) {
if (k.getCompanyName().toLowerCase().contains(request.getText().toLowerCase())) {
if (!response.addResult(new SearchResult(k), k.getCompanyName())) {
return;
}
}
}
} catch (NullPointerException npe) {
}
}
private static class SearchResult implements Runnable, Lookup.Provider {
private final Company company;
private final InstanceContent ic = new InstanceContent();
private final Lookup lookup = new AbstractLookup(ic);
public SearchResult(Company c) {
this.company= c;
}
#Override
public void run() {
ic.add(company);
try {
StatusDisplayer.getDefault().setStatusText(
company.getCompanyName()
+ ", " + company.getAddress()
+ ", " + company.getCity());
} catch (NullPointerException npe) {
}
}
#Override
public Lookup getLookup() {
return lookup;
}
}
}
And this is partof the code which listens for a Company object :
public final class ManagementPodatakaTopComponent extends TopComponent {
private Lookup.Result<Company> companyLookup = null;
...
private Company selectedCompany;
...
#Override
public void componentOpened() {
companyLookup = Utilities.actionsGlobalContext().lookupResult(Company.class);
companyLookup .addLookupListener(new LookupListener() {
#Override
public void resultChanged(LookupEvent le) {
Lookup.Result k = (Lookup.Result) le.getSource();
Collection<Company> cs = k.allInstances();
for (Company k1 : cs) {
selectedCompany = k1;
}
setCompanyTextFields(selectedCompany);
jTP_DataManagement.setVisible(true);
jPanel_Entiteti.setVisible(true);
}
});
}
A SearchResult which provides a lookup? Never seen this in the wild.
Please ask at nbdev#netbeans.org to get better feedback (probably from one of the NB devs)
I finally managed somehow to get what I want :
First off, define interface:
public interface ICodes {
public Code getCode();
}
Then, we implement quick search :
#ServiceProvider(service = ICodes.class)
public class ClientServicesQS implements SearchProvider, ICodes {
private static Code code = null;
#Override
public void evaluate(SearchRequest request, SearchResponse response) {
try {
for (Code c : INFSYS.queries.INFSistemQuery.ByersByName(request.getText())) {
if (!response.addResult(new SearchResult(c),
c.getName() + " ,Code: " + c.getByerCode()
+ (c.getAddress() != null ? ", " + c.getAddress() : ""))) {
return;
}
}
} catch (NullPointerException npe) {
StatusDisplayer.getDefault().setStatusText("Error." + npe.getMessage());
}
}
#Override
public Code getCode() {
return ClientServicesQS.sifra;
}
private static class SearchResult implements Runnable {
private final Code code;
public SearchResult(Code code) {
this.code= code;
}
#Override
public void run() {
try {
ClientServicesQS.code= this.code;
OpenTopComponent("ClientServicesTopComponent");
} catch (NullPointerException e) {
Display.messageBaloon("Error.", e.toString() + ", " + e.getMessage(), Display.TYPE_MESSAGE.ERROR);
}
}
}
}
Finally, we implement lookup in other module through platform.
Because I want to call lookup whenever componentOpen, oe componentActivated is invoked, it is usefull first to define :
private void QSCodeSearch() {
try {
ICode ic= Lookup.getDefault().lookup(ICode.class);
if ((code = ic.getCode()) != null) {
.
.
.
// setup UI components with data from lookup
.
.
.
}
} catch (Exception e) {
}
}
And when topcomponent is activated, we call QSCodeSearch() in :
#Override
public void componentOpened() {
...
QSCodeSearch()
...
}
...
#Override
public void requestActive() {
...
QSCodeSearch()
...
}

How to use Retry rule along with Errorcollector rule in junit

I am using Error collector rule in my application( selenium web driver). I am able to thrown exception and continue next line of code with help of error collector rule. But right now i want to re run failed test again ( 3 times) to ensure they are really failed. hence i am using Retry rule. But this rule when applied individually it get executed ( Retry rule with Assert command) `but when written with error collector is doesn't get executed any reason....
Please help me with sample code.
TestBase.java:
public class TestBase {
#Rule
public ErrorCollector collector = new ErrorCollector();
private boolean fatal;
public TestBase() {
fatal=true;
}
public void assertEquals( String msg, Object expected, Object actual) {
if(getFatal()) {
Assert.assertEquals(msg,expected, actual);
} else {
collector.checkThat(msg, actual, CoreMatchers.is(expected));
}
}
public void setFatal(boolean fatalFlag) {
fatal = fatalFlag;
}
public boolean getFatal() {
return fatal;
}
}
BFMNew.java
public class BFMNew extends TestBase {
#Rule
public Retry retry = new Retry(3);
#Rule
public ErrorCollector errocol = new ErrorCollector();
#Before
public void setUp() throws Exception {
System.out.println(" in before");
}
// ===========Re run fail test custom====
public class Retry implements TestRule {
private int retryCount;
public Retry(int retryCount) {
this.retryCount = retryCount;
}
public Statement apply(Statement base, Description description) {
return statement(base, description);
}
private Statement statement(final Statement base,
final Description description) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
Throwable caughtThrowable = null;
// implement retry logic here
for (int i = 0; i < retryCount; i++) {
try {
base.evaluate();
return;
} catch (Throwable t) {
caughtThrowable = t;
System.err.println(description.getDisplayName()
+ ": run " + (i + 1) + " failed");
}
}
System.err.println(description.getDisplayName()
+ ": giving up after " + retryCount + " failures");
throw caughtThrowable;
}
};
}
}
#Test
public void one() {
setFatal(false);
Boolean IsLogin = true; //Here function will come for login
Boolean IsPost = null;
Boolean IsStnComment = null;
Boolean IsPhotoUpload = false;
if( IsLogin ) {
IsPost = false;
assertEquals("Failed to Insert Post", true, IsPost);
}
System.out.println(" After Post ");
assertEquals("Failed to upload photo", true, IsPhotoUpload);
if( IsPost ) {
IsStnComment = false;
//assertEquals("Failed to Insert Comment", true, IsStnComment);
}
System.out.println("After comment");
}
The problem is with rules ordering. You should make ErrorCollector to be outer rule and Retry inner rule. Starting from junit 4.10 use this
class YourTest {
private ErrorCollector collector = new ErrorCollector();
private Retry retry = Retry(3);
#Rule
public TestRule chain= RuleChain
.outerRule(collector)
.around(retry);
// tests using collector go here
}

Cometd : It seems that ServerChannel lose some subscribers

I used cometd to realize notification push, but i found out the following issue :
After log in the system, at the beginning, the client can receive message from server, but after wait pretty long time or do some other operation, the client may not receive message from server any more. Did anyone else encountered this problem? Thanks in Advance.
Blow is my code :
1. Client Code
var cometd = dojox.cometd;cometd.websocketEnabled = false;
cometd.init(url);
cometd.subscribe("/foo/new", function(message) {
......The business logic......
}
);
2. The ServletContextAttributeListener that integrate with AbstractService
public class BayeuxInitializerListener implements ServletContextAttributeListener {
private static final String CLIENT_CHANNEL = "/foo/new";
#Override
public void attributeAdded(ServletContextAttributeEvent event) {
if(BayeuxServer.ATTRIBUTE.equals(event.getName())) {
BayeuxServer bayeuxServer = (BayeuxServer) event.getValue();
boolean isCreated = bayeuxServer.createIfAbsent(CLIENT_CHANNEL, new ConfigurableServerChannel.Initializer() {
#Override
public void configureChannel(ConfigurableServerChannel channel) {
channel.setPersistent(true);
}
});
new MyService(bayeuxServer);
}
}
3. Service
public class MyService extends AbstractService {
private static final Logger logger = Logger.getLogger(MyService .class);
private static final String CLIENT_CHANNEL = "/foo/new";
private static final String LISTENER_CHANNEL = "/service/notification";
public MyService(BayeuxServer bayeuxServer) {
super(bayeuxServer, "notification");
this.addService(LISTENER_CHANNEL, "processNotification");
}
public void processNotification(ServerSession serverSession, Map<String, Object> data) {
LocalSession localSession = this.getLocalSession();
if(logger.isDebugEnabled()) {
logger.debug("Local Session : " + localSession.getId() + ".");
}
ServerChannel serverChannel = this.getBayeux().getChannel(CLIENT_CHANNEL)
Set<ServerSession> subscribers = serverChannel.getSubscribers();
if(0 == subscribers.size()) {
logger.info("There are no subcribers for " + CLIENT_CHANNEL + ".");
}
for(ServerSession subscriber : subscribers) {
logger.info("The subscriber for " + CLIENT_CHANNEL + " : " + subscriber.getId() + ".");
}
serverChannel.publish(localSession, data, null);
}