/**
   * Initiates the shutdown of all connected ViewNodes.
   *
   * @return false if a connection is already in progress, true otherwise.
   * @throws IOException
   */
  public boolean shutdown() throws IOException {
    if (shutDown) {
      getLogger().info("Suppressing duplicate attempt to shut down");
      return false;
    }

    shutDown = true;
    running = false;

    List<ViewNode> nodesToRemove = new ArrayList<ViewNode>();
    for (ViewNode node : couchNodes) {
      if (node != null) {
        String hostname = node.getSocketAddress().getHostName();
        if (node.hasWriteOps()) {
          getLogger().warn("Shutting down " + hostname + " with ops waiting to be written");
        } else {
          getLogger().info("Node " + hostname + " has no ops in the queue");
        }
        node.shutdown();
        nodesToRemove.add(node);
      }
    }

    for (ViewNode node : nodesToRemove) {
      couchNodes.remove(node);
    }

    return true;
  }
Пример #2
0
    public View inflate(Context context, View parent) throws Exception {
      View view = create(context, (ViewGroup) parent);

      for (ViewNode child : children) {
        child.inflate(context, view);
      }

      invokeOnFinishInflate(view);
      return view;
    }
Пример #3
0
 @Override
 protected void processResourceXml(File xmlFile, Document document, boolean isSystem)
     throws Exception {
   ViewNode topLevelNode = new ViewNode("top-level", new HashMap<String, String>(), isSystem);
   processChildren(document.getChildNodes(), topLevelNode);
   String layoutName =
       xmlFile.getParentFile().getName() + "/" + xmlFile.getName().replace(".xml", "");
   if (isSystem) {
     layoutName = "android:" + layoutName;
   }
   viewNodesByLayoutName.put(layoutName, topLevelNode.getChildren().get(0));
 }
  private static void loadProperties(ViewNode node, String data) {
    int start = 0;
    boolean stop;

    do {
      int index = data.indexOf('=', start);
      ViewNode.Property property = new ViewNode.Property();
      property.name = data.substring(start, index);

      int index2 = data.indexOf(',', index + 1);
      int length = Integer.parseInt(data.substring(index + 1, index2));
      start = index2 + 1 + length;
      property.value = data.substring(index2 + 1, index2 + 1 + length);

      node.properties.add(property);
      node.namedProperties.put(property.name, property);

      stop = start >= data.length();
      if (!stop) {
        start += 1;
      }
    } while (!stop);

    Collections.sort(
        node.properties,
        new Comparator<ViewNode.Property>() {
          public int compare(ViewNode.Property source, ViewNode.Property destination) {
            return source.name.compareTo(destination.name);
          }
        });

    node.decode();
  }
  /**
   * Create ViewNode connections and queue them up for connect.
   *
   * <p>This method also defines the connection params for each connection, including the default
   * settings like timeouts and the user agent string.
   *
   * @param addrs addresses of all the nodes it should connect to.
   * @return Returns a list of the ViewNodes.
   * @throws IOException
   */
  private List<ViewNode> createConnections(List<InetSocketAddress> addrs) throws IOException {

    List<ViewNode> nodeList = new LinkedList<ViewNode>();

    for (InetSocketAddress a : addrs) {
      HttpParams params = new SyncBasicHttpParams();
      params
          .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
          .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000)
          .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
          .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
          .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
          .setParameter(CoreProtocolPNames.USER_AGENT, "Couchbase Java Client 1.0.2");

      HttpProcessor httpproc =
          new ImmutableHttpProcessor(
              new HttpRequestInterceptor[] {
                new RequestContent(), new RequestTargetHost(),
                new RequestConnControl(), new RequestUserAgent(),
                new RequestExpectContinue(),
              });

      AsyncNHttpClientHandler protocolHandler =
          new AsyncNHttpClientHandler(
              httpproc,
              new MyHttpRequestExecutionHandler(this),
              new DefaultConnectionReuseStrategy(),
              new DirectByteBufferAllocator(),
              params);
      protocolHandler.setEventListener(new EventLogger());

      AsyncConnectionManager connMgr =
          new AsyncConnectionManager(
              new HttpHost(a.getHostName(), a.getPort()),
              NUM_CONNS,
              protocolHandler,
              params,
              new RequeueOpCallback(this));
      getLogger().info("Added %s to connect queue", a.getHostName());

      ViewNode node = connFactory.createViewNode(a, connMgr);
      node.init();
      nodeList.add(node);
    }

    return nodeList;
  }
 /**
  * Write an operation to the next ViewNode.
  *
  * <p>To make sure that the operations are distributed throughout the cluster, the ViewNode is
  * changed every time a new operation is added. Since the getNextNode() method increments the
  * ViewNode IDs and calculates the modulo, the nodes are selected in a round-robin fashion.
  *
  * @param op the operation to run.
  */
 public void addOp(final HttpOperation op) {
   rlock.lock();
   try {
     if (couchNodes.isEmpty()) {
       getLogger().error("No server connections. Cancelling op.");
       op.cancel();
     } else {
       boolean success = false;
       int retries = 0;
       do {
         if (retries >= MAX_ADDOP_RETRIES) {
           op.cancel();
           break;
         }
         ViewNode node = couchNodes.get(getNextNode());
         if (node.isShuttingDown() || !hasActiveVBuckets(node)) {
           continue;
         }
         if (retries > 0) {
           getLogger()
               .debug(
                   "Retrying view operation #"
                       + op.hashCode()
                       + " on node: "
                       + node.getSocketAddress());
         }
         success = node.writeOp(op);
         if (retries > 0 && success) {
           getLogger()
               .debug(
                   "Successfully wrote #"
                       + op.hashCode()
                       + " on node: "
                       + node.getSocketAddress()
                       + " after "
                       + retries
                       + " retries.");
         }
         retries++;
       } while (!success);
     }
   } finally {
     rlock.unlock();
   }
 }
  private static void updateIndices(ViewNode root) {
    if (root == null) return;

    root.computeIndex();

    for (ViewNode node : root.children) {
      updateIndices(node);
    }
  }
Пример #8
0
 private View inflateView(
     Context context, String layoutName, Map<String, String> attributes, View parent) {
   ViewNode viewNode = getViewNodeByLayoutName(layoutName);
   if (viewNode == null) {
     throw new RuntimeException("Could not find layout " + layoutName);
   }
   try {
     if (attributes != null) {
       for (Map.Entry<String, String> entry : attributes.entrySet()) {
         if (!entry.getKey().equals("layout")) {
           viewNode.attributes.put(entry.getKey(), entry.getValue());
         }
       }
     }
     return viewNode.inflate(context, parent);
   } catch (I18nException e) {
     throw e;
   } catch (Exception e) {
     throw new RuntimeException("error inflating " + layoutName, e);
   }
 }
  /**
   * Reconfigures the connected ViewNodes.
   *
   * <p>When a reconfiguration event happens, new ViewNodes may need to be added or old ones need to
   * be removed from the current configuration. This method takes care that those operations are
   * performed in the correct order and are executed in a thread-safe manner.
   *
   * @param bucket the bucket which has been rebalanced.
   */
  public void reconfigure(Bucket bucket) {
    reconfiguring = true;

    try {
      // get a new collection of addresses from the received config
      HashSet<SocketAddress> newServerAddresses = new HashSet<SocketAddress>();
      List<InetSocketAddress> newServers =
          AddrUtil.getAddressesFromURL(bucket.getConfig().getCouchServers());
      for (InetSocketAddress server : newServers) {
        // add parsed address to our collections
        newServerAddresses.add(server);
      }

      // split current nodes to "odd nodes" and "stay nodes"
      ArrayList<ViewNode> shutdownNodes = new ArrayList<ViewNode>();
      ArrayList<ViewNode> stayNodes = new ArrayList<ViewNode>();
      ArrayList<InetSocketAddress> stayServers = new ArrayList<InetSocketAddress>();

      wlock.lock();
      try {
        for (ViewNode current : couchNodes) {
          if (newServerAddresses.contains(current.getSocketAddress())) {
            stayNodes.add(current);
            stayServers.add((InetSocketAddress) current.getSocketAddress());
          } else {
            shutdownNodes.add(current);
          }
        }

        // prepare a collection of addresses for new nodes
        newServers.removeAll(stayServers);

        // create a collection of new nodes
        List<ViewNode> newNodes = createConnections(newServers);

        // merge stay nodes with new nodes
        List<ViewNode> mergedNodes = new ArrayList<ViewNode>();
        mergedNodes.addAll(stayNodes);
        mergedNodes.addAll(newNodes);

        couchNodes = mergedNodes;
      } finally {
        wlock.unlock();
      }

      // shutdown for the oddNodes
      for (ViewNode qa : shutdownNodes) {
        try {
          qa.shutdown();
        } catch (IOException e) {
          getLogger().error("Error shutting down connection to " + qa.getSocketAddress());
        }
      }

    } catch (IOException e) {
      getLogger().error("Connection reconfiguration failed", e);
    } finally {
      reconfiguring = false;
    }
  }
Пример #10
0
  private void processNode(Node node, ViewNode parent) {
    String name = node.getNodeName();
    NamedNodeMap attributes = node.getAttributes();
    Map<String, String> attrMap = new HashMap<String, String>();
    if (attributes != null) {
      int length = attributes.getLength();
      for (int i = 0; i < length; i++) {
        Node attr = attributes.item(i);
        attrMap.put(attr.getNodeName(), attr.getNodeValue());
      }
    }

    if (name.equals("requestFocus")) {
      parent.attributes.put("android:focus", "true");
      parent.requestFocusOverride = true;
    } else if (!name.startsWith("#")) {
      ViewNode viewNode = new ViewNode(name, attrMap, parent.isSystem);
      if (parent != null) parent.addChild(viewNode);

      processChildren(node.getChildNodes(), viewNode);
    }
  }
 /**
  * Check if the {@link ViewNode} has active VBuckets.
  *
  * @param node the node to check
  * @return true or false if it has active VBuckets.
  */
 private boolean hasActiveVBuckets(ViewNode node) {
   DefaultConfig config = (DefaultConfig) connFactory.getVBucketConfig();
   return config.nodeHasActiveVBuckets(node.getSocketAddress());
 }
Пример #12
0
  @SuppressWarnings("empty-statement")
  public static ViewHierarchyScene loadScene(IDevice device, Window window) {
    ViewHierarchyScene scene = new ViewHierarchyScene();

    // Read the views tree
    Socket socket = null;
    BufferedReader in = null;
    BufferedWriter out = null;

    String line;

    try {
      System.out.println("==> Starting client");

      socket = new Socket();
      socket.connect(new InetSocketAddress("127.0.0.1", DeviceBridge.getDeviceLocalPort(device)));

      out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
      in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));

      System.out.println("==> DUMP");

      out.write("DUMP " + window.encode());
      out.newLine();
      out.flush();

      Stack<ViewNode> stack = new Stack<ViewNode>();

      boolean setRoot = true;
      ViewNode lastNode = null;
      int lastWhitespaceCount = Integer.MAX_VALUE;

      while ((line = in.readLine()) != null) {
        if ("DONE.".equalsIgnoreCase(line)) {
          break;
        }

        int whitespaceCount = countFrontWhitespace(line);
        if (lastWhitespaceCount < whitespaceCount) {
          stack.push(lastNode);
        } else if (!stack.isEmpty()) {
          final int count = lastWhitespaceCount - whitespaceCount;
          for (int i = 0; i < count; i++) {
            stack.pop();
          }
        }

        lastWhitespaceCount = whitespaceCount;
        line = line.trim();
        int index = line.indexOf(' ');

        lastNode = new ViewNode();
        lastNode.name = line.substring(0, index);

        line = line.substring(index + 1);
        loadProperties(lastNode, line);

        scene.addNode(lastNode);

        if (setRoot) {
          scene.setRoot(lastNode);
          setRoot = false;
        }

        if (!stack.isEmpty()) {
          final ViewNode parent = stack.peek();
          final String edge = parent.name + lastNode.name;
          scene.addEdge(edge);
          scene.setEdgeSource(edge, parent);
          scene.setEdgeTarget(edge, lastNode);
          lastNode.parent = parent;
          parent.children.add(lastNode);
        }
      }

      updateIndices(scene.getRoot());

    } catch (IOException ex) {
      Exceptions.printStackTrace(ex);
    } finally {
      try {
        if (out != null) {
          out.close();
        }
        if (in != null) {
          in.close();
        }
        socket.close();
      } catch (IOException ex) {
        Exceptions.printStackTrace(ex);
      }
    }

    System.out.println("==> DONE");

    return scene;
  }