Automated merge with http://hg.netbeans.org/main/contrib
authorTomas Zezula <tzezula@netbeans.org>
Tue, 11 Feb 2014 18:05:20 +0100
changeset 181702aed3988eeb1
parent 18168 1ff3fe3f312c
parent 18169 2e3f7791d289
child 18171 95232a041be0
child 18189 267611db7bc8
Automated merge with http://hg.netbeans.org/main/contrib
     1.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/debugger/ActiveSessions.java	Tue Feb 11 13:50:52 2014 +0100
     1.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/debugger/ActiveSessions.java	Tue Feb 11 18:05:20 2014 +0100
     1.3 @@ -107,48 +107,48 @@
     1.4              @NonNull final WorkspaceResolver.Context context,
     1.5              @NonNull final EndPoint.Env env) {
     1.6          Parameters.notNull("context", context); //NOI18N
     1.7 -        Parameters.notNull("env", env); //NOI18N
     1.8 -        final int id = sequencer.incrementAndGet();
     1.9 -        Session session;
    1.10 +        Parameters.notNull("env", env); //NOI18N        
    1.11 +        Session session = null;
    1.12 +        final DebugInterceptor di = DebugInterceptor.getInstance();
    1.13          try {
    1.14 -            for (session = findSession(); session == null; session = findSession()) {
    1.15 -                LOG.info("Wating for debugger....");    //NOI18N
    1.16 +            for (session = findSession(); session == null && di.isDebuggerStarting(); session = findSession()) {
    1.17 +                LOG.info("Wating for debugger session....");    //NOI18N
    1.18                  Thread.sleep(1000);
    1.19              }
    1.20          } catch (InterruptedException ie) {
    1.21 -            return -1;
    1.22 +            //Pass
    1.23          }
    1.24 -        if (session != null) {
    1.25 -            if (active.putIfAbsent(id, new Data(id, context, env, session)) != null) {
    1.26 -                throw new IllegalStateException("Trying to reuse active session");  //NOI18N
    1.27 -            }
    1.28 -            final JPDADebugger jpda = session.lookupFirst(null, JPDADebugger.class);
    1.29 -            if (!(jpda instanceof JPDADebuggerImpl)) {
    1.30 -                throw new IllegalStateException("Wrong debugger service.");    //NOI18N
    1.31 -            }
    1.32 -            try {
    1.33 -                jpda.waitRunning();
    1.34 -                //Hack:
    1.35 -                //Now comes the fun, JPDADebuggerImpl is full of races
    1.36 -                //so after wait we need to busy wait. Inverted spin-park :-)
    1.37 -                while (jpda.getState() < 2) {
    1.38 -                    Thread.sleep(500);
    1.39 -                }
    1.40 -            } catch (DebuggerStartException | InterruptedException ex) {
    1.41 -                LOG.log(Level.WARNING, "Debugger start Exception: {0}", ex);
    1.42 -                return -1;
    1.43 -            }
    1.44 -            final int state = jpda.getState();
    1.45 -            if (state == JPDADebugger.STATE_RUNNING || state == JPDADebugger.STATE_STOPPED) {
    1.46 -                return id;
    1.47 -            } else {
    1.48 -                LOG.log(Level.WARNING, "Wrong debugger state: {0}", state);
    1.49 -                return -1;
    1.50 -            }
    1.51 -        } else {
    1.52 +        if (session == null) {
    1.53              LOG.warning("No debugger session");
    1.54              return -1;
    1.55          }
    1.56 +        final int id = sequencer.incrementAndGet();
    1.57 +        if (active.putIfAbsent(id, new Data(id, context, env, session)) != null) {
    1.58 +            throw new IllegalStateException("Trying to reuse active session");  //NOI18N
    1.59 +        }
    1.60 +        final JPDADebugger jpda = session.lookupFirst(null, JPDADebugger.class);
    1.61 +        if (!(jpda instanceof JPDADebuggerImpl)) {
    1.62 +            throw new IllegalStateException("Wrong debugger service.");    //NOI18N
    1.63 +        }
    1.64 +        try {
    1.65 +            jpda.waitRunning();
    1.66 +            //Hack:
    1.67 +            //Now comes the fun, JPDADebuggerImpl is full of races
    1.68 +            //so after wait we need to busy wait. Inverted spin-park :-)
    1.69 +            while (jpda.getState() < 2) {
    1.70 +                Thread.sleep(500);
    1.71 +            }
    1.72 +        } catch (DebuggerStartException | InterruptedException ex) {
    1.73 +            LOG.log(Level.WARNING, "Debugger start Exception: {0}", ex);
    1.74 +            return -1;
    1.75 +        }
    1.76 +        final int state = jpda.getState();
    1.77 +        if (state == JPDADebugger.STATE_RUNNING || state == JPDADebugger.STATE_STOPPED) {
    1.78 +            return id;
    1.79 +        } else {
    1.80 +            LOG.log(Level.WARNING, "Wrong debugger state: {0}", state);
    1.81 +            return -1;
    1.82 +        }        
    1.83      }
    1.84  
    1.85      @CheckForNull
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/debugger/DebugInterceptor.java	Tue Feb 11 18:05:20 2014 +0100
     2.3 @@ -0,0 +1,110 @@
     2.4 +/*
     2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     2.6 + *
     2.7 + * Copyright 2014 Oracle and/or its affiliates. All rights reserved.
     2.8 + *
     2.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    2.10 + * Other names may be trademarks of their respective owners.
    2.11 + *
    2.12 + * The contents of this file are subject to the terms of either the GNU
    2.13 + * General Public License Version 2 only ("GPL") or the Common
    2.14 + * Development and Distribution License("CDDL") (collectively, the
    2.15 + * "License"). You may not use this file except in compliance with the
    2.16 + * License. You can obtain a copy of the License at
    2.17 + * http://www.netbeans.org/cddl-gplv2.html
    2.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    2.19 + * specific language governing permissions and limitations under the
    2.20 + * License.  When distributing the software, include this License Header
    2.21 + * Notice in each file and include the License file at
    2.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    2.23 + * particular file as subject to the "Classpath" exception as provided
    2.24 + * by Oracle in the GPL Version 2 section of the License file that
    2.25 + * accompanied this code. If applicable, add the following below the
    2.26 + * License Header, with the fields enclosed by brackets [] replaced by
    2.27 + * your own identifying information:
    2.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    2.29 + *
    2.30 + * If you wish your version of this file to be governed by only the CDDL
    2.31 + * or only the GPL Version 2, indicate your decision by adding
    2.32 + * "[Contributor] elects to include this software in this distribution
    2.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    2.34 + * single choice of license, a recipient has the option to distribute
    2.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    2.36 + * to extend the choice of license to its licensees as provided above.
    2.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    2.38 + * Version 2 license, then the option applies only if the new code is
    2.39 + * made subject to such option by the copyright holder.
    2.40 + *
    2.41 + * Contributor(s):
    2.42 + *
    2.43 + * Portions Copyrighted 2014 Sun Microsystems, Inc.
    2.44 + */
    2.45 +
    2.46 +package org.netbeans.modules.dew4nb.services.debugger;
    2.47 +
    2.48 +import java.util.logging.Logger;
    2.49 +import org.netbeans.api.annotations.common.NonNull;
    2.50 +import org.netbeans.api.debugger.DebuggerManager;
    2.51 +import org.netbeans.api.debugger.Session;
    2.52 +import org.netbeans.modules.dew4nb.endpoint.EndPoint;
    2.53 +import org.netbeans.modules.dew4nb.services.project.ProjectAction;
    2.54 +import org.netbeans.modules.dew4nb.services.project.ProjectActionInterceptor;
    2.55 +import org.netbeans.spi.project.ActionProvider;
    2.56 +import org.openide.util.Lookup;
    2.57 +import org.openide.util.lookup.ServiceProvider;
    2.58 +
    2.59 +/**
    2.60 + *
    2.61 + * @author Tomas Zezula
    2.62 + */
    2.63 +@ServiceProvider(service = ProjectActionInterceptor.class)
    2.64 +public final class DebugInterceptor implements ProjectActionInterceptor {
    2.65 +
    2.66 +    private static final Logger LOG = Logger.getLogger(DebugInterceptor.class.getName());
    2.67 +
    2.68 +    private volatile boolean debuggerStarting;
    2.69 +
    2.70 +    @Override
    2.71 +    public void started(
    2.72 +            @NonNull final EndPoint.Env env,
    2.73 +            @NonNull final ProjectAction request) {
    2.74 +        LOG.fine("started");    //NOI18N
    2.75 +        if (ActionProvider.COMMAND_DEBUG.equals(request.getAction())) {
    2.76 +            LOG.fine("debug");    //NOI18N
    2.77 +            debuggerStarting = true;
    2.78 +            killAllExistingSessions();
    2.79 +        }
    2.80 +    }
    2.81 +
    2.82 +    @Override
    2.83 +    public void finished(
    2.84 +        @NonNull final EndPoint.Env env,
    2.85 +        @NonNull final ProjectAction request,
    2.86 +        final boolean result) {
    2.87 +        LOG.fine("finished");    //NOI18N
    2.88 +        if (ActionProvider.COMMAND_DEBUG.equals(request.getAction())) {
    2.89 +            LOG.fine("debug");    //NOI18N
    2.90 +            debuggerStarting = false;
    2.91 +        }
    2.92 +    }
    2.93 +
    2.94 +    boolean isDebuggerStarting() {
    2.95 +        return debuggerStarting;
    2.96 +    }
    2.97 +
    2.98 +    private void killAllExistingSessions() {
    2.99 +        for (Session s : DebuggerManager.getDebuggerManager().getSessions()) {
   2.100 +            s.kill();
   2.101 +        }
   2.102 +    }
   2.103 +
   2.104 +    @NonNull
   2.105 +    static DebugInterceptor getInstance() {
   2.106 +        for (ProjectActionInterceptor i : Lookup.getDefault().lookupAll(ProjectActionInterceptor.class)) {
   2.107 +            if (i.getClass() == DebugInterceptor.class) {
   2.108 +                return DebugInterceptor.class.cast(i);
   2.109 +            }
   2.110 +        }
   2.111 +        throw new IllegalStateException("Not registered in Lookup");    //NOI18N
   2.112 +    }
   2.113 +}
     3.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/project/IORedirectProvider.java	Tue Feb 11 13:50:52 2014 +0100
     3.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/project/IORedirectProvider.java	Tue Feb 11 18:05:20 2014 +0100
     3.3 @@ -60,6 +60,7 @@
     3.4  import org.netbeans.api.annotations.common.NullAllowed;
     3.5  import org.netbeans.modules.dew4nb.endpoint.EndPoint;
     3.6  import org.netbeans.modules.dew4nb.endpoint.Status;
     3.7 +import org.openide.util.Pair;
     3.8  import org.openide.util.Parameters;
     3.9  import org.openide.util.lookup.ServiceProvider;
    3.10  import org.openide.windows.IOProvider;
    3.11 @@ -74,11 +75,8 @@
    3.12  @ServiceProvider(service = IOProvider.class, position = 0)
    3.13  public class IORedirectProvider extends IOProvider {
    3.14  
    3.15 -    static final String PROP_STATE = "state";   //NOI18N
    3.16 -    static final String PROP_TYPE = "type"; //NOI18N
    3.17 -
    3.18      private static final Pattern EMPTY_STR = Pattern.compile("^\\s*$"); //NOI18N
    3.19 -    private static final ThreadLocal<EndPoint.Env> currentEnv = new ThreadLocal<>();
    3.20 +    private static final ThreadLocal<Pair<EndPoint.Env,String>> currentEnv = new ThreadLocal<>();
    3.21      private static final Object threadsLock = new Object();
    3.22      //@GuardedBy("threadsLock")
    3.23      private static final Map<RedirectIO,Collection<Reference<Thread>>> activeThreads =
    3.24 @@ -87,9 +85,17 @@
    3.25      public IORedirectProvider() {}
    3.26  
    3.27  
    3.28 -    static void bindEnv(@NonNull final EndPoint.Env env) {
    3.29 +    static void bindEnv(
    3.30 +        @NonNull final EndPoint.Env env,
    3.31 +        @NonNull final ProjectAction request) {
    3.32          Parameters.notNull("env", env); //NOI18N
    3.33 -        currentEnv.set(env);
    3.34 +        Parameters.notNull("request", request); //NOI18N
    3.35 +        if (ProjectMessageType.invokeAction != request.getType()) {
    3.36 +            throw new IllegalArgumentException(String.valueOf(request.getType()));
    3.37 +        }
    3.38 +        currentEnv.set(Pair.<EndPoint.Env,String>of(
    3.39 +            env,
    3.40 +            request.getState()));
    3.41      }
    3.42  
    3.43      static void unbindEnv() {
    3.44 @@ -182,6 +188,7 @@
    3.45  
    3.46          private final AtomicBoolean closed;
    3.47          private volatile EndPoint.Env env;
    3.48 +        private volatile String state;
    3.49  
    3.50          RedirectIO() {
    3.51              this.closed = new AtomicBoolean();
    3.52 @@ -259,7 +266,7 @@
    3.53              @NonNull final String data,
    3.54              final boolean err) {
    3.55              env.sendObject(createResponse(
    3.56 -                    env,
    3.57 +                    state,
    3.58                      null,
    3.59                      err?
    3.60                          null :
    3.61 @@ -273,7 +280,7 @@
    3.62          void closeImpl() {
    3.63              if (!closed.getAndSet(true)) {
    3.64                  env.sendObject(createResponse(
    3.65 -                    env,
    3.66 +                    state,
    3.67                      BuildResult.success,
    3.68                      null,
    3.69                      null,
    3.70 @@ -284,7 +291,7 @@
    3.71          void openUrlImpl(@NonNull final URL url) {
    3.72              Parameters.notNull("url", url); //NOI18N
    3.73              env.sendObject(createResponse(
    3.74 -                env,
    3.75 +                state,
    3.76                  null,
    3.77                  null,
    3.78                  null,
    3.79 @@ -295,10 +302,12 @@
    3.80              synchronized (threadsLock) {
    3.81                  activeThreads.remove(this);
    3.82              }
    3.83 -            env = currentEnv.get();
    3.84 -            if (env == null) {
    3.85 +            final Pair<EndPoint.Env,String> p = currentEnv.get();
    3.86 +            if (p == null) {
    3.87                  throw new IllegalStateException();
    3.88              }
    3.89 +            env = p.first();
    3.90 +            state = p.second();
    3.91              closed.set(false);
    3.92          }
    3.93  
    3.94 @@ -426,18 +435,14 @@
    3.95  
    3.96      @NonNull
    3.97      private static InvokeProjectActionResult createResponse(
    3.98 -            @NonNull final EndPoint.Env env,
    3.99 +            @NonNull final String state,
   3.100              @NullAllowed final BuildResult result,
   3.101              @NullAllowed final String stdOut,
   3.102              @NullAllowed final String stdErr,
   3.103              @NullAllowed final Collection<? extends URL> urls) {
   3.104 -        Parameters.notNull("env", env); //NOI18N
   3.105 -        final ProjectMessageType type = env.getProperty(PROP_TYPE, ProjectMessageType.class);
   3.106 -        Parameters.notNull("type", type); //NOI18N
   3.107 -        final String state = env.getProperty(PROP_STATE, String.class);
   3.108          Parameters.notNull("state", state); //NOI18N
   3.109          final InvokeProjectActionResult res = new InvokeProjectActionResult();
   3.110 -        res.setType(type);
   3.111 +        res.setType(ProjectMessageType.invokeAction);
   3.112          res.setState(state);
   3.113          res.setStatus(Status.done);
   3.114          res.setResult(result);
     4.1 --- a/dew4nb/src/org/netbeans/modules/dew4nb/services/project/InvokeProjectActionHandler.java	Tue Feb 11 13:50:52 2014 +0100
     4.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/project/InvokeProjectActionHandler.java	Tue Feb 11 18:05:20 2014 +0100
     4.3 @@ -43,6 +43,7 @@
     4.4  package org.netbeans.modules.dew4nb.services.project;
     4.5  
     4.6  import javax.swing.SwingUtilities;
     4.7 +import org.netbeans.api.annotations.common.NonNull;
     4.8  import org.netbeans.api.project.FileOwnerQuery;
     4.9  import org.netbeans.api.project.Project;
    4.10  import org.netbeans.modules.dew4nb.endpoint.AsyncRequestHandler;
    4.11 @@ -50,9 +51,11 @@
    4.12  import org.netbeans.modules.dew4nb.endpoint.RequestHandler;
    4.13  import org.netbeans.modules.dew4nb.endpoint.Status;
    4.14  import org.netbeans.modules.dew4nb.spi.WorkspaceResolver;
    4.15 +import org.netbeans.spi.project.ActionProgress;
    4.16  import org.netbeans.spi.project.ActionProvider;
    4.17  import org.openide.filesystems.FileObject;
    4.18  import org.openide.util.Lookup;
    4.19 +import org.openide.util.Parameters;
    4.20  import org.openide.util.lookup.Lookups;
    4.21  import org.openide.util.lookup.ServiceProvider;
    4.22  
    4.23 @@ -97,22 +100,51 @@
    4.24                      SwingUtilities.invokeLater(new Runnable() {
    4.25                          @Override
    4.26                          public void run() {
    4.27 -                            env.setProperty(IORedirectProvider.PROP_TYPE, request.getType());
    4.28 -                            env.setProperty(IORedirectProvider.PROP_STATE, request.getState());
    4.29 -                            IORedirectProvider.bindEnv(env);
    4.30 -                            try {
    4.31 -                                ap.invokeAction(
    4.32 -                                    request.getAction(),
    4.33 -                                    Lookups.fixed(file, prj));
    4.34 -                            } finally {
    4.35 -                                IORedirectProvider.unbindEnv();
    4.36 -                            }
    4.37 +                            ap.invokeAction(
    4.38 +                                request.getAction(),
    4.39 +                                Lookups.fixed(
    4.40 +                                    file,
    4.41 +                                    prj,
    4.42 +                                    new Progress(env, request)));
    4.43                          }
    4.44                      });
    4.45                  }
    4.46              }
    4.47          }
    4.48          return res;
    4.49 -    }    
    4.50 +    }
    4.51 +
    4.52 +    private static final class Progress extends ActionProgress {
    4.53 +
    4.54 +        private static final Lookup.Result<ProjectActionInterceptor> impls =
    4.55 +                Lookup.getDefault().lookupResult(ProjectActionInterceptor.class);
    4.56 +        private final EndPoint.Env env;
    4.57 +        private final ProjectAction request;
    4.58 +
    4.59 +        Progress(
    4.60 +                @NonNull final EndPoint.Env env,
    4.61 +                @NonNull final ProjectAction request) {
    4.62 +            Parameters.notNull("env", env); //NOI18N
    4.63 +            Parameters.notNull("request", request); //NOI18N
    4.64 +            this.env = env;
    4.65 +            this.request = request;            
    4.66 +            IORedirectProvider.bindEnv(this.env, this.request);
    4.67 +            for (ProjectActionInterceptor interceptor : impls.allInstances()) {
    4.68 +                interceptor.started(this.env, this.request);
    4.69 +            }
    4.70 +        }
    4.71 +
    4.72 +        @Override
    4.73 +        protected void started() {
    4.74 +        }
    4.75 +
    4.76 +        @Override
    4.77 +        public void finished(boolean success) {
    4.78 +            IORedirectProvider.unbindEnv();
    4.79 +            for (ProjectActionInterceptor interceptor : impls.allInstances()) {
    4.80 +                interceptor.finished(this.env, this.request, success);
    4.81 +            }
    4.82 +        }
    4.83 +    }
    4.84  
    4.85  }
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/dew4nb/src/org/netbeans/modules/dew4nb/services/project/ProjectActionInterceptor.java	Tue Feb 11 18:05:20 2014 +0100
     5.3 @@ -0,0 +1,55 @@
     5.4 +/*
     5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     5.6 + *
     5.7 + * Copyright 2014 Oracle and/or its affiliates. All rights reserved.
     5.8 + *
     5.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    5.10 + * Other names may be trademarks of their respective owners.
    5.11 + *
    5.12 + * The contents of this file are subject to the terms of either the GNU
    5.13 + * General Public License Version 2 only ("GPL") or the Common
    5.14 + * Development and Distribution License("CDDL") (collectively, the
    5.15 + * "License"). You may not use this file except in compliance with the
    5.16 + * License. You can obtain a copy of the License at
    5.17 + * http://www.netbeans.org/cddl-gplv2.html
    5.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    5.19 + * specific language governing permissions and limitations under the
    5.20 + * License.  When distributing the software, include this License Header
    5.21 + * Notice in each file and include the License file at
    5.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    5.23 + * particular file as subject to the "Classpath" exception as provided
    5.24 + * by Oracle in the GPL Version 2 section of the License file that
    5.25 + * accompanied this code. If applicable, add the following below the
    5.26 + * License Header, with the fields enclosed by brackets [] replaced by
    5.27 + * your own identifying information:
    5.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    5.29 + *
    5.30 + * If you wish your version of this file to be governed by only the CDDL
    5.31 + * or only the GPL Version 2, indicate your decision by adding
    5.32 + * "[Contributor] elects to include this software in this distribution
    5.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    5.34 + * single choice of license, a recipient has the option to distribute
    5.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    5.36 + * to extend the choice of license to its licensees as provided above.
    5.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    5.38 + * Version 2 license, then the option applies only if the new code is
    5.39 + * made subject to such option by the copyright holder.
    5.40 + *
    5.41 + * Contributor(s):
    5.42 + *
    5.43 + * Portions Copyrighted 2014 Sun Microsystems, Inc.
    5.44 + */
    5.45 +
    5.46 +package org.netbeans.modules.dew4nb.services.project;
    5.47 +
    5.48 +import org.netbeans.api.annotations.common.NonNull;
    5.49 +import org.netbeans.modules.dew4nb.endpoint.EndPoint;
    5.50 +
    5.51 +/**
    5.52 + *
    5.53 + * @author Tomas Zezula
    5.54 + */
    5.55 +public interface ProjectActionInterceptor {
    5.56 +    void started(@NonNull EndPoint.Env env, @NonNull final ProjectAction request);
    5.57 +    void finished(@NonNull EndPoint.Env env, @NonNull final ProjectAction request, boolean result);
    5.58 +}