/** * 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; }
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; }
@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); } }
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; } }
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()); }
@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; }