Example usage for com.google.gwt.core.client JsArrayString get

List of usage examples for com.google.gwt.core.client JsArrayString get

Introduction

In this page you can find the example usage for com.google.gwt.core.client JsArrayString get.

Prototype

public final native String get(int index) ;

Source Link

Document

Gets the value at a given index.

Usage

From source file:com.risevision.viewer.client.data.ViewerDataProvider.java

License:Open Source License

public static void retrieveData(String reason) {
    if (state == IDLE_STATE) {
        // [AD] moved this function to after the data is retrieved - workaround for Core bug 
        // where the Viewer API and Channel Token calls can't be made at the same time 
        //         channelController.init(channelCommand);

        String url;/*from  w w w  .ja  v  a 2s  . co  m*/

        url = Global.DATA_SERVER_URL.replace("{0}", ViewerEntryPoint.getType());
        url = url.replace("{1}", ViewerEntryPoint.getId());

        int viewerWidth = Window.getClientWidth();
        int viewerHeight = Window.getClientHeight();

        String sysInfo = ViewerEntryPoint.getSysInfo();
        JsArrayString browserInfo = ViewerHtmlUtils.getBrowserVersion();

        String updateTicket = ChannelConnectionController.getUpdateTicket();
        updateTicket = updateTicket == null ? "" : "&ticket=" + updateTicket;

        String fullUrl = url + "?sig=" + ViewerDataController.getSig() + updateTicket + "&"
                + Global.VIEWER_URL_IDENTIFIER
                + (RiseUtils.strIsNullOrEmpty(sysInfo) ? "" : "&" + URL.decodeQueryString(sysInfo)) + "&cn="
                + browserInfo.get(0) + "&cv=" + browserInfo.get(1) + "&width=" + viewerWidth + "&height="
                + viewerHeight + "&callback=?";

        state = WAITING_STATE;

        // start 60 second timer for timeout of data retrieval
        apiTimer.schedule(ViewerDataController.MINUTE_UPDATE_INTERVAL);
        ViewerHtmlUtils.logExternalMessage("viewer data retrieval", reason);
        getDataNative(fullUrl);
    } else {
        state = CONTENT_STATE;
    }
}

From source file:com.vaadin.client.ApplicationConfiguration.java

License:Apache License

public void addComponentInheritanceInfo(ValueMap valueMap) {
    JsArrayString keyArray = valueMap.getKeyArray();
    for (int i = 0; i < keyArray.length(); i++) {
        String key = keyArray.get(i);
        int value = valueMap.getInt(key);
        componentInheritanceMap.put(Integer.parseInt(key), value);
    }//  w ww  .ja  v  a  2s.  co  m
}

From source file:com.vaadin.client.ApplicationConfiguration.java

License:Apache License

public void addComponentMappings(ValueMap valueMap, WidgetSet widgetSet) {
    JsArrayString keyArray = valueMap.getKeyArray();
    for (int i = 0; i < keyArray.length(); i++) {
        String key = keyArray.get(i).intern();
        int value = valueMap.getInt(key);
        tagToServerSideClassName.put(value, key);
    }/*from   w  w  w . j a v a2  s .c  o  m*/

    for (int i = 0; i < keyArray.length(); i++) {
        String key = keyArray.get(i).intern();
        int value = valueMap.getInt(key);
        widgetSet.ensureConnectorLoaded(value, this);
    }
}

From source file:com.vaadin.client.ApplicationConnection.java

License:Apache License

public void loadStyleDependencies(JsArrayString dependencies) {
    // Assuming no reason to interpret in a defined order
    ResourceLoadListener resourceLoadListener = new ResourceLoadListener() {
        @Override//  w w  w .  j  a v a 2  s  .  co m
        public void onLoad(ResourceLoadEvent event) {
            ApplicationConfiguration.endDependencyLoading();
        }

        @Override
        public void onError(ResourceLoadEvent event) {
            getLogger().severe(event.getResourceUrl()
                    + " could not be loaded, or the load detection failed because the stylesheet is empty.");
            // The show must go on
            onLoad(event);
        }
    };
    ResourceLoader loader = ResourceLoader.get();
    for (int i = 0; i < dependencies.length(); i++) {
        String url = translateVaadinUri(dependencies.get(i));
        ApplicationConfiguration.startDependencyLoading();
        loader.loadStylesheet(url, resourceLoadListener);
    }
}

From source file:com.vaadin.client.ApplicationConnection.java

License:Apache License

public void loadScriptDependencies(final JsArrayString dependencies) {
    if (dependencies.length() == 0) {
        return;//ww  w .j  a va2s .  c  o  m
    }

    // Listener that loads the next when one is completed
    ResourceLoadListener resourceLoadListener = new ResourceLoadListener() {
        @Override
        public void onLoad(ResourceLoadEvent event) {
            if (dependencies.length() != 0) {
                String url = translateVaadinUri(dependencies.shift());
                ApplicationConfiguration.startDependencyLoading();
                // Load next in chain (hopefully already preloaded)
                event.getResourceLoader().loadScript(url, this);
            }
            // Call start for next before calling end for current
            ApplicationConfiguration.endDependencyLoading();
        }

        @Override
        public void onError(ResourceLoadEvent event) {
            getLogger().severe(event.getResourceUrl() + " could not be loaded.");
            // The show must go on
            onLoad(event);
        }
    };

    ResourceLoader loader = ResourceLoader.get();

    // Start chain by loading first
    String url = translateVaadinUri(dependencies.shift());
    ApplicationConfiguration.startDependencyLoading();
    loader.loadScript(url, resourceLoadListener);

    if (ResourceLoader.supportsInOrderScriptExecution()) {
        for (int i = 0; i < dependencies.length(); i++) {
            String preloadUrl = translateVaadinUri(dependencies.get(i));
            loader.loadScript(preloadUrl, null);
        }
    } else {
        // Preload all remaining
        for (int i = 0; i < dependencies.length(); i++) {
            String preloadUrl = translateVaadinUri(dependencies.get(i));
            loader.preloadResource(preloadUrl, null);
        }
    }
}

From source file:com.vaadin.client.communication.MessageHandler.java

License:Apache License

protected void handleJSON(final ValueMap json) {
    final int serverId = getServerId(json);

    if (isResynchronize(json) && !isNextExpectedMessage(serverId)) {
        // Resynchronize request. We must remove any old pending
        // messages and ensure this is handled next. Otherwise we
        // would keep waiting for an older message forever (if this
        // is triggered by forceHandleMessage)
        getLogger().info(/*www .  j  a  v a  2 s  .c o m*/
                "Received resync message with id " + serverId + " while waiting for " + getExpectedServerId());
        lastSeenServerSyncId = serverId - 1;
        removeOldPendingMessages();
    }

    boolean locked = !responseHandlingLocks.isEmpty();

    if (locked || !isNextExpectedMessage(serverId)) {
        // Cannot or should not handle this message right now, either
        // because of locks or because it's an out-of-order message

        if (locked) {
            // Some component is doing something that can't be interrupted
            // (e.g. animation that should be smooth). Enqueue the UIDL
            // message for later processing.
            getLogger().info("Postponing UIDL handling due to lock...");
        } else {
            // Unexpected server id
            if (serverId <= lastSeenServerSyncId) {
                // Why is the server re-sending an old package? Ignore it
                getLogger().warning("Received message with server id " + serverId + " but have already seen "
                        + lastSeenServerSyncId + ". Ignoring it");
                endRequestIfResponse(json);
                return;
            }

            // We are waiting for an earlier message...
            getLogger().info(
                    "Received message with server id " + serverId + " but expected " + getExpectedServerId()
                            + ". Postponing handling until the missing message(s) have been received");
        }
        pendingUIDLMessages.add(new PendingUIDLMessage(json));
        if (!forceHandleMessage.isRunning()) {
            forceHandleMessage.schedule(MAX_SUSPENDED_TIMEOUT);
        }
        return;
    }

    final Date start = new Date();
    /*
     * Lock response handling to avoid a situation where something pushed
     * from the server gets processed while waiting for e.g. lazily loaded
     * connectors that are needed for processing the current message.
     */
    final Object lock = new Object();
    suspendReponseHandling(lock);

    getLogger().info("Handling message from server");
    connection.fireEvent(new ResponseHandlingStartedEvent(connection));

    // Client id must be updated before server id, as server id update can
    // cause a resync (which must use the updated id)
    if (json.containsKey(ApplicationConstants.CLIENT_TO_SERVER_ID)) {
        int serverNextExpected = json.getInt(ApplicationConstants.CLIENT_TO_SERVER_ID);
        getMessageSender().setClientToServerMessageId(serverNextExpected, isResynchronize(json));
    }

    if (serverId != -1) {
        /*
         * Use sync id unless explicitly set as undefined, as is done by
         * e.g. critical server-side notifications
         */
        lastSeenServerSyncId = serverId;
    }

    // Handle redirect
    if (json.containsKey("redirect")) {
        String url = json.getValueMap("redirect").getString("url");
        getLogger().info("redirecting to " + url);
        WidgetUtil.redirect(url);
        return;
    }

    final MultiStepDuration handleUIDLDuration = new MultiStepDuration();

    // Get security key
    if (json.containsKey(ApplicationConstants.UIDL_SECURITY_TOKEN_ID)) {
        csrfToken = json.getString(ApplicationConstants.UIDL_SECURITY_TOKEN_ID);
    }
    getLogger().info(" * Handling resources from server");

    if (json.containsKey("resources")) {
        ValueMap resources = json.getValueMap("resources");
        JsArrayString keyArray = resources.getKeyArray();
        int l = keyArray.length();
        for (int i = 0; i < l; i++) {
            String key = keyArray.get(i);
            connection.setResource(key, resources.getAsString(key));
        }
    }
    handleUIDLDuration.logDuration(" * Handling resources from server completed", 10);

    getLogger().info(" * Handling type inheritance map from server");

    if (json.containsKey("typeInheritanceMap")) {
        connection.getConfiguration().addComponentInheritanceInfo(json.getValueMap("typeInheritanceMap"));
    }
    handleUIDLDuration.logDuration(" * Handling type inheritance map from server completed", 10);

    getLogger().info("Handling type mappings from server");

    if (json.containsKey("typeMappings")) {
        connection.getConfiguration().addComponentMappings(json.getValueMap("typeMappings"),
                connection.getWidgetSet());

    }

    getLogger().info("Handling resource dependencies");
    if (json.containsKey("scriptDependencies")) {
        connection.loadScriptDependencies(json.getJSStringArray("scriptDependencies"));
    }
    if (json.containsKey("styleDependencies")) {
        connection.loadStyleDependencies(json.getJSStringArray("styleDependencies"));
    }

    handleUIDLDuration.logDuration(" * Handling type mappings from server completed", 10);
    /*
     * Hook for e.g. TestBench to get details about server peformance
     */
    if (json.containsKey("timings")) {
        serverTimingInfo = json.getValueMap("timings");
    }

    Command c = new Command() {
        private boolean onlyNoLayoutUpdates = true;

        @Override
        public void execute() {
            assert serverId == -1 || serverId == lastSeenServerSyncId;

            handleUIDLDuration.logDuration(" * Loading widgets completed", 10);

            Profiler.enter("Handling meta information");
            ValueMap meta = null;
            if (json.containsKey("meta")) {
                getLogger().info(" * Handling meta information");
                meta = json.getValueMap("meta");
                if (meta.containsKey("repaintAll")) {
                    prepareRepaintAll();
                }
                if (meta.containsKey("timedRedirect")) {
                    final ValueMap timedRedirect = meta.getValueMap("timedRedirect");
                    if (redirectTimer != null) {
                        redirectTimer.cancel();
                    }
                    redirectTimer = new Timer() {
                        @Override
                        public void run() {
                            WidgetUtil.redirect(timedRedirect.getString("url"));
                        }
                    };
                    sessionExpirationInterval = timedRedirect.getInt("interval");
                }
            }
            Profiler.leave("Handling meta information");

            if (redirectTimer != null) {
                redirectTimer.schedule(1000 * sessionExpirationInterval);
            }

            updatingState = true;

            double processUidlStart = Duration.currentTimeMillis();

            // Ensure that all connectors that we are about to update exist
            JsArrayString createdConnectorIds = createConnectorsIfNeeded(json);

            // Update states, do not fire events
            JsArrayObject<StateChangeEvent> pendingStateChangeEvents = updateConnectorState(json,
                    createdConnectorIds);

            /*
             * Doing this here so that locales are available also to the
             * connectors which get a state change event before the UI.
             */
            Profiler.enter("Handling locales");
            getLogger().info(" * Handling locales");
            // Store locale data
            LocaleService.addLocales(getUIConnector().getState().localeServiceState.localeData);
            Profiler.leave("Handling locales");

            // Update hierarchy, do not fire events
            ConnectorHierarchyUpdateResult connectorHierarchyUpdateResult = updateConnectorHierarchy(json);

            // Fire hierarchy change events
            sendHierarchyChangeEvents(connectorHierarchyUpdateResult.events);

            updateCaptions(pendingStateChangeEvents, connectorHierarchyUpdateResult.parentChangedIds);

            delegateToWidget(pendingStateChangeEvents);

            // Fire state change events.
            sendStateChangeEvents(pendingStateChangeEvents);

            // Update of legacy (UIDL) style connectors
            updateVaadin6StyleConnectors(json);

            // Handle any RPC invocations done on the server side
            handleRpcInvocations(json);

            if (json.containsKey("dd")) {
                // response contains data for drag and drop service
                VDragAndDropManager.get().handleServerResponse(json.getValueMap("dd"));
            }

            unregisterRemovedConnectors(connectorHierarchyUpdateResult.detachedConnectorIds);

            getLogger().info("handleUIDLMessage: " + (Duration.currentTimeMillis() - processUidlStart) + " ms");

            updatingState = false;

            Profiler.enter("Layout processing");
            try {
                LayoutManager layoutManager = getLayoutManager();
                if (!onlyNoLayoutUpdates) {
                    layoutManager.setEverythingNeedsMeasure();
                }
                if (layoutManager.isLayoutNeeded()) {
                    layoutManager.layoutNow();
                }
            } catch (final Throwable e) {
                getLogger().log(Level.SEVERE, "Error processing layouts", e);
            }
            Profiler.leave("Layout processing");

            if (ApplicationConfiguration.isDebugMode()) {
                Profiler.enter("Dumping state changes to the console");
                getLogger().info(" * Dumping state changes to the console");
                VConsole.dirUIDL(json, connection);
                Profiler.leave("Dumping state changes to the console");
            }

            if (meta != null) {
                Profiler.enter("Error handling");
                if (meta.containsKey("appError")) {
                    ValueMap error = meta.getValueMap("appError");

                    VNotification.showError(connection, error.getString("caption"), error.getString("message"),
                            error.getString("details"), error.getString("url"));

                    connection.setApplicationRunning(false);
                }
                Profiler.leave("Error handling");
            }

            // TODO build profiling for widget impl loading time

            lastProcessingTime = (int) ((new Date().getTime()) - start.getTime());
            totalProcessingTime += lastProcessingTime;
            if (bootstrapTime == 0) {

                double fetchStart = getFetchStartTime();
                if (fetchStart != 0) {
                    int time = (int) (Duration.currentTimeMillis() - fetchStart);
                    getLogger().log(Level.INFO, "First response processed " + time + " ms after fetchStart");
                }

                bootstrapTime = calculateBootstrapTime();
                if (Profiler.isEnabled() && bootstrapTime != -1) {
                    Profiler.logBootstrapTimings();
                }
            }

            getLogger().info(" Processing time was " + String.valueOf(lastProcessingTime) + "ms");
            getLogger().info("Referenced paintables: " + getConnectorMap().size());

            endRequestIfResponse(json);
            resumeResponseHandling(lock);

            if (Profiler.isEnabled()) {
                Scheduler.get().scheduleDeferred(new ScheduledCommand() {
                    @Override
                    public void execute() {
                        Profiler.logTimings();
                        Profiler.reset();
                    }
                });
            }
        }

        /**
         * Properly clean up any old stuff to ensure everything is properly
         * reinitialized.
         */
        private void prepareRepaintAll() {
            String uiConnectorId = getUIConnector().getConnectorId();
            if (uiConnectorId == null) {
                // Nothing to clear yet
                return;
            }

            // Create fake server response that says that the uiConnector
            // has no children
            JsonObject fakeHierarchy = Json.createObject();
            fakeHierarchy.put(uiConnectorId, Json.createArray());
            JsonObject fakeJson = Json.createObject();
            fakeJson.put("hierarchy", fakeHierarchy);
            ValueMap fakeValueMap = ((JavaScriptObject) fakeJson.toNative()).cast();

            // Update hierarchy based on the fake response
            ConnectorHierarchyUpdateResult connectorHierarchyUpdateResult = updateConnectorHierarchy(
                    fakeValueMap);

            // Send hierarchy events based on the fake update
            sendHierarchyChangeEvents(connectorHierarchyUpdateResult.events);

            // Unregister all the old connectors that have now been removed
            unregisterRemovedConnectors(connectorHierarchyUpdateResult.detachedConnectorIds);

            getLayoutManager().cleanMeasuredSizes();
        }

        private void updateCaptions(JsArrayObject<StateChangeEvent> pendingStateChangeEvents,
                FastStringSet parentChangedIds) {
            Profiler.enter("updateCaptions");

            /*
             * Find all components that might need a caption update based on
             * pending state and hierarchy changes
             */
            FastStringSet needsCaptionUpdate = FastStringSet.create();
            needsCaptionUpdate.addAll(parentChangedIds);

            // Find components with potentially changed caption state
            int size = pendingStateChangeEvents.size();
            for (int i = 0; i < size; i++) {
                StateChangeEvent event = pendingStateChangeEvents.get(i);
                if (VCaption.mightChange(event)) {
                    ServerConnector connector = event.getConnector();
                    needsCaptionUpdate.add(connector.getConnectorId());
                }
            }

            ConnectorMap connectorMap = getConnectorMap();

            // Update captions for all suitable candidates
            JsArrayString dump = needsCaptionUpdate.dump();
            int needsUpdateLength = dump.length();
            for (int i = 0; i < needsUpdateLength; i++) {
                String childId = dump.get(i);
                ServerConnector child = connectorMap.getConnector(childId);

                if (child instanceof ComponentConnector
                        && ((ComponentConnector) child).delegateCaptionHandling()) {
                    ServerConnector parent = child.getParent();
                    if (parent instanceof HasComponentsConnector) {
                        Profiler.enter("HasComponentsConnector.updateCaption");
                        ((HasComponentsConnector) parent).updateCaption((ComponentConnector) child);
                        Profiler.leave("HasComponentsConnector.updateCaption");
                    }
                }
            }

            Profiler.leave("updateCaptions");
        }

        private void delegateToWidget(JsArrayObject<StateChangeEvent> pendingStateChangeEvents) {
            Profiler.enter("@DelegateToWidget");

            getLogger().info(" * Running @DelegateToWidget");

            // Keep track of types that have no @DelegateToWidget in their
            // state to optimize performance
            FastStringSet noOpTypes = FastStringSet.create();

            int size = pendingStateChangeEvents.size();
            for (int eventIndex = 0; eventIndex < size; eventIndex++) {
                StateChangeEvent sce = pendingStateChangeEvents.get(eventIndex);
                ServerConnector connector = sce.getConnector();
                if (connector instanceof ComponentConnector) {
                    String className = connector.getClass().getName();
                    if (noOpTypes.contains(className)) {
                        continue;
                    }
                    ComponentConnector component = (ComponentConnector) connector;

                    Type stateType = AbstractConnector.getStateType(component);
                    JsArrayString delegateToWidgetProperties = stateType.getDelegateToWidgetProperties();
                    if (delegateToWidgetProperties == null) {
                        noOpTypes.add(className);
                        continue;
                    }

                    int length = delegateToWidgetProperties.length();
                    for (int i = 0; i < length; i++) {
                        String propertyName = delegateToWidgetProperties.get(i);
                        if (sce.hasPropertyChanged(propertyName)) {
                            Property property = stateType.getProperty(propertyName);
                            String method = property.getDelegateToWidgetMethodName();
                            Profiler.enter("doDelegateToWidget");
                            doDelegateToWidget(component, property, method);
                            Profiler.leave("doDelegateToWidget");
                        }
                    }

                }
            }

            Profiler.leave("@DelegateToWidget");
        }

        private void doDelegateToWidget(ComponentConnector component, Property property, String methodName) {
            Type type = TypeData.getType(component.getClass());
            try {
                Type widgetType = type.getMethod("getWidget").getReturnType();
                Widget widget = component.getWidget();

                Object propertyValue = property.getValue(component.getState());

                widgetType.getMethod(methodName).invoke(widget, propertyValue);
            } catch (NoDataException e) {
                throw new RuntimeException("Missing data needed to invoke @DelegateToWidget for "
                        + component.getClass().getSimpleName(), e);
            }
        }

        /**
         * Sends the state change events created while updating the state
         * information.
         * 
         * This must be called after hierarchy change listeners have been
         * called. At least caption updates for the parent are strange if
         * fired from state change listeners and thus calls the parent
         * BEFORE the parent is aware of the child (through a
         * ConnectorHierarchyChangedEvent)
         * 
         * @param pendingStateChangeEvents
         *            The events to send
         */
        private void sendStateChangeEvents(JsArrayObject<StateChangeEvent> pendingStateChangeEvents) {
            Profiler.enter("sendStateChangeEvents");
            getLogger().info(" * Sending state change events");

            int size = pendingStateChangeEvents.size();
            for (int i = 0; i < size; i++) {
                StateChangeEvent sce = pendingStateChangeEvents.get(i);
                try {
                    sce.getConnector().fireEvent(sce);
                } catch (final Throwable e) {
                    getLogger().log(Level.SEVERE, "Error sending state change events", e);
                }
            }

            Profiler.leave("sendStateChangeEvents");
        }

        private void verifyConnectorHierarchy() {
            Profiler.enter("verifyConnectorHierarchy - this is only performed in debug mode");

            JsArrayObject<ServerConnector> currentConnectors = getConnectorMap().getConnectorsAsJsArray();
            int size = currentConnectors.size();
            for (int i = 0; i < size; i++) {
                ServerConnector c = currentConnectors.get(i);
                if (c.getParent() != null) {
                    if (!c.getParent().getChildren().contains(c)) {
                        getLogger().severe("ERROR: Connector " + c.getConnectorId()
                                + " is connected to a parent but the parent (" + c.getParent().getConnectorId()
                                + ") does not contain the connector");
                    }
                } else if (c == getUIConnector()) {
                    // UIConnector for this connection, ignore
                } else if (c instanceof WindowConnector && getUIConnector().hasSubWindow((WindowConnector) c)) {
                    // Sub window attached to this UIConnector, ignore
                } else {
                    // The connector has been detached from the
                    // hierarchy but was not unregistered.
                    getLogger().severe("ERROR: Connector " + c.getConnectorId()
                            + " is not attached to a parent but has not been unregistered");
                }

            }

            Profiler.leave("verifyConnectorHierarchy - this is only performed in debug mode");
        }

        private void unregisterRemovedConnectors(FastStringSet detachedConnectors) {
            Profiler.enter("unregisterRemovedConnectors");

            JsArrayString detachedArray = detachedConnectors.dump();
            for (int i = 0; i < detachedArray.length(); i++) {
                ServerConnector connector = getConnectorMap().getConnector(detachedArray.get(i));

                Profiler.enter("unregisterRemovedConnectors unregisterConnector");
                getConnectorMap().unregisterConnector(connector);
                Profiler.leave("unregisterRemovedConnectors unregisterConnector");
            }

            if (ApplicationConfiguration.isDebugMode()) {
                // Do some extra checking if we're in debug mode (i.e. debug
                // window is open)
                verifyConnectorHierarchy();
            }

            getLogger().info("* Unregistered " + detachedArray.length() + " connectors");
            Profiler.leave("unregisterRemovedConnectors");
        }

        private JsArrayString createConnectorsIfNeeded(ValueMap json) {
            getLogger().info(" * Creating connectors (if needed)");

            JsArrayString createdConnectors = JavaScriptObject.createArray().cast();
            if (!json.containsKey("types")) {
                return createdConnectors;
            }

            Profiler.enter("Creating connectors");

            ValueMap types = json.getValueMap("types");
            JsArrayString keyArray = types.getKeyArray();
            for (int i = 0; i < keyArray.length(); i++) {
                try {
                    String connectorId = keyArray.get(i);
                    ServerConnector connector = getConnectorMap().getConnector(connectorId);
                    if (connector != null) {
                        continue;
                    }

                    // Always do layouts if there's at least one new
                    // connector
                    onlyNoLayoutUpdates = false;

                    int connectorType = Integer.parseInt(types.getString(connectorId));

                    Class<? extends ServerConnector> connectorClass = connection.getConfiguration()
                            .getConnectorClassByEncodedTag(connectorType);

                    // Connector does not exist so we must create it
                    if (connectorClass != getUIConnector().getClass()) {
                        // create, initialize and register the paintable
                        Profiler.enter("ApplicationConnection.getConnector");
                        connector = connection.getConnector(connectorId, connectorType);
                        Profiler.leave("ApplicationConnection.getConnector");

                        createdConnectors.push(connectorId);
                    } else {
                        // First UIConnector update. Before this the
                        // UIConnector has been created but not
                        // initialized as the connector id has not been
                        // known
                        getConnectorMap().registerConnector(connectorId, getUIConnector());
                        getUIConnector().doInit(connectorId, connection);
                        createdConnectors.push(connectorId);
                    }
                } catch (final Throwable e) {
                    getLogger().log(Level.SEVERE, "Error handling type data", e);
                }
            }

            Profiler.leave("Creating connectors");

            return createdConnectors;
        }

        private void updateVaadin6StyleConnectors(ValueMap json) {
            Profiler.enter("updateVaadin6StyleConnectors");

            JsArray<ValueMap> changes = json.getJSValueMapArray("changes");
            int length = changes.length();

            // Must always do layout if there's even a single legacy update
            if (length != 0) {
                onlyNoLayoutUpdates = false;
            }

            getLogger().info(" * Passing UIDL to Vaadin 6 style connectors");
            // update paintables
            for (int i = 0; i < length; i++) {
                try {
                    final UIDL change = changes.get(i).cast();
                    final UIDL uidl = change.getChildUIDL(0);
                    String connectorId = uidl.getId();

                    final ComponentConnector legacyConnector = (ComponentConnector) getConnectorMap()
                            .getConnector(connectorId);
                    if (legacyConnector instanceof Paintable) {
                        String key = null;
                        if (Profiler.isEnabled()) {
                            key = "updateFromUIDL for " + legacyConnector.getClass().getSimpleName();
                            Profiler.enter(key);
                        }

                        ((Paintable) legacyConnector).updateFromUIDL(uidl, connection);

                        if (Profiler.isEnabled()) {
                            Profiler.leave(key);
                        }
                    } else if (legacyConnector == null) {
                        getLogger().severe("Received update for " + uidl.getTag()
                                + ", but there is no such paintable (" + connectorId + ") rendered.");
                    } else {
                        getLogger().severe("Server sent Vaadin 6 style updates for "
                                + Util.getConnectorString(legacyConnector)
                                + " but this is not a Vaadin 6 Paintable");
                    }

                } catch (final Throwable e) {
                    getLogger().log(Level.SEVERE, "Error handling UIDL", e);
                }
            }

            Profiler.leave("updateVaadin6StyleConnectors");
        }

        private void sendHierarchyChangeEvents(JsArrayObject<ConnectorHierarchyChangeEvent> events) {
            int eventCount = events.size();
            if (eventCount == 0) {
                return;
            }
            Profiler.enter("sendHierarchyChangeEvents");

            getLogger().info(" * Sending hierarchy change events");
            for (int i = 0; i < eventCount; i++) {
                ConnectorHierarchyChangeEvent event = events.get(i);
                try {
                    logHierarchyChange(event);
                    event.getConnector().fireEvent(event);
                } catch (final Throwable e) {
                    getLogger().log(Level.SEVERE, "Error sending hierarchy change events", e);
                }
            }

            Profiler.leave("sendHierarchyChangeEvents");
        }

        private void logHierarchyChange(ConnectorHierarchyChangeEvent event) {
            if (true) {
                // Always disabled for now. Can be enabled manually
                return;
            }

            getLogger().info("Hierarchy changed for " + Util.getConnectorString(event.getConnector()));
            String oldChildren = "* Old children: ";
            for (ComponentConnector child : event.getOldChildren()) {
                oldChildren += Util.getConnectorString(child) + " ";
            }
            getLogger().info(oldChildren);

            String newChildren = "* New children: ";
            HasComponentsConnector parent = (HasComponentsConnector) event.getConnector();
            for (ComponentConnector child : parent.getChildComponents()) {
                newChildren += Util.getConnectorString(child) + " ";
            }
            getLogger().info(newChildren);
        }

        private JsArrayObject<StateChangeEvent> updateConnectorState(ValueMap json,
                JsArrayString createdConnectorIds) {
            JsArrayObject<StateChangeEvent> events = JavaScriptObject.createArray().cast();
            getLogger().info(" * Updating connector states");
            if (!json.containsKey("state")) {
                return events;
            }

            Profiler.enter("updateConnectorState");

            FastStringSet remainingNewConnectors = FastStringSet.create();
            remainingNewConnectors.addAll(createdConnectorIds);

            // set states for all paintables mentioned in "state"
            ValueMap states = json.getValueMap("state");
            JsArrayString keyArray = states.getKeyArray();
            for (int i = 0; i < keyArray.length(); i++) {
                try {
                    String connectorId = keyArray.get(i);
                    ServerConnector connector = getConnectorMap().getConnector(connectorId);
                    if (null != connector) {
                        Profiler.enter("updateConnectorState inner loop");
                        if (Profiler.isEnabled()) {
                            Profiler.enter("Decode connector state " + connector.getClass().getSimpleName());
                        }

                        JavaScriptObject jso = states.getJavaScriptObject(connectorId);
                        JsonObject stateJson = Util.jso2json(jso);

                        if (connector instanceof HasJavaScriptConnectorHelper) {
                            ((HasJavaScriptConnectorHelper) connector).getJavascriptConnectorHelper()
                                    .setNativeState(jso);
                        }

                        SharedState state = connector.getState();
                        Type stateType = new Type(state.getClass().getName(), null);

                        if (onlyNoLayoutUpdates) {
                            Profiler.enter("updateConnectorState @NoLayout handling");
                            for (String propertyName : stateJson.keys()) {
                                Property property = stateType.getProperty(propertyName);
                                if (!property.isNoLayout()) {
                                    onlyNoLayoutUpdates = false;
                                    break;
                                }
                            }
                            Profiler.leave("updateConnectorState @NoLayout handling");
                        }

                        Profiler.enter("updateConnectorState decodeValue");
                        JsonDecoder.decodeValue(stateType, stateJson, state, connection);
                        Profiler.leave("updateConnectorState decodeValue");

                        if (Profiler.isEnabled()) {
                            Profiler.leave("Decode connector state " + connector.getClass().getSimpleName());
                        }

                        Profiler.enter("updateConnectorState create event");

                        boolean isNewConnector = remainingNewConnectors.contains(connectorId);
                        if (isNewConnector) {
                            remainingNewConnectors.remove(connectorId);
                        }

                        StateChangeEvent event = new StateChangeEvent(connector, stateJson, isNewConnector);
                        events.add(event);
                        Profiler.leave("updateConnectorState create event");

                        Profiler.leave("updateConnectorState inner loop");
                    }
                } catch (final Throwable e) {
                    getLogger().log(Level.SEVERE, "Error updating connector states", e);
                }
            }

            Profiler.enter("updateConnectorState newWithoutState");
            // Fire events for properties using the default value for newly
            // created connectors even if there were no state changes
            JsArrayString dump = remainingNewConnectors.dump();
            int length = dump.length();
            for (int i = 0; i < length; i++) {
                String connectorId = dump.get(i);
                ServerConnector connector = getConnectorMap().getConnector(connectorId);

                StateChangeEvent event = new StateChangeEvent(connector, Json.createObject(), true);

                events.add(event);

            }
            Profiler.leave("updateConnectorState newWithoutState");

            Profiler.leave("updateConnectorState");

            return events;
        }

        /**
         * Updates the connector hierarchy and returns a list of events that
         * should be fired after update of the hierarchy and the state is
         * done.
         * 
         * @param json
         *            The JSON containing the hierarchy information
         * @return A collection of events that should be fired when update
         *         of hierarchy and state is complete and a list of all
         *         connectors for which the parent has changed
         */
        private ConnectorHierarchyUpdateResult updateConnectorHierarchy(ValueMap json) {
            ConnectorHierarchyUpdateResult result = new ConnectorHierarchyUpdateResult();

            getLogger().info(" * Updating connector hierarchy");

            Profiler.enter("updateConnectorHierarchy");

            FastStringSet maybeDetached = FastStringSet.create();
            FastStringSet hasHierarchy = FastStringSet.create();

            // Process regular hierarchy data
            if (json.containsKey("hierarchy")) {
                ValueMap hierarchies = json.getValueMap("hierarchy");
                JsArrayString hierarchyKeys = hierarchies.getKeyArray();
                for (int i = 0; i < hierarchyKeys.length(); i++) {
                    String connectorId = hierarchyKeys.get(i);
                    JsArrayString childConnectorIds = hierarchies.getJSStringArray(connectorId);
                    hasHierarchy.add(connectorId);

                    updateConnectorHierarchy(connectorId, childConnectorIds, maybeDetached, result);
                }
            }

            // Assume empty hierarchy for connectors with state updates but
            // no hierarchy data
            if (json.containsKey("state")) {
                JsArrayString stateKeys = json.getValueMap("state").getKeyArray();

                JsArrayString emptyArray = JavaScriptObject.createArray().cast();

                for (int i = 0; i < stateKeys.length(); i++) {
                    String connectorId = stateKeys.get(i);
                    if (!hasHierarchy.contains(connectorId)) {
                        updateConnectorHierarchy(connectorId, emptyArray, maybeDetached, result);
                    }
                }
            }

            Profiler.enter("updateConnectorHierarchy detach removed connectors");

            /*
             * Connector is in maybeDetached at this point if it has been
             * removed from its parent but not added to any other parent
             */
            JsArrayString maybeDetachedArray = maybeDetached.dump();
            for (int i = 0; i < maybeDetachedArray.length(); i++) {
                ServerConnector removed = getConnectorMap().getConnector(maybeDetachedArray.get(i));
                recursivelyDetach(removed, result.events, result.detachedConnectorIds);
            }

            Profiler.leave("updateConnectorHierarchy detach removed connectors");

            if (result.events.size() != 0) {
                onlyNoLayoutUpdates = false;
            }

            Profiler.leave("updateConnectorHierarchy");

            return result;

        }

        /**
         * Updates the hierarchy for a connector
         * 
         * @param connectorId
         *            the id of the connector to update
         * @param childConnectorIds
         *            array of child connector ids
         * @param maybeDetached
         *            set of connectors that are maybe detached
         * @param result
         *            the hierarchy update result
         */
        private void updateConnectorHierarchy(String connectorId, JsArrayString childConnectorIds,
                FastStringSet maybeDetached, ConnectorHierarchyUpdateResult result) {
            try {
                Profiler.enter("updateConnectorHierarchy hierarchy entry");

                ConnectorMap connectorMap = getConnectorMap();

                ServerConnector parentConnector = connectorMap.getConnector(connectorId);
                int childConnectorSize = childConnectorIds.length();

                Profiler.enter("updateConnectorHierarchy find new connectors");

                List<ServerConnector> newChildren = new ArrayList<ServerConnector>();
                List<ComponentConnector> newComponents = new ArrayList<ComponentConnector>();
                for (int connectorIndex = 0; connectorIndex < childConnectorSize; connectorIndex++) {
                    String childConnectorId = childConnectorIds.get(connectorIndex);
                    ServerConnector childConnector = connectorMap.getConnector(childConnectorId);
                    if (childConnector == null) {
                        getLogger().severe("Hierarchy claims that " + childConnectorId + " is a child for "
                                + connectorId + " (" + parentConnector.getClass().getName()
                                + ") but no connector with id " + childConnectorId + " has been registered. "
                                + "More information might be available in the server-side log if assertions are enabled");
                        continue;
                    }
                    newChildren.add(childConnector);
                    if (childConnector instanceof ComponentConnector) {
                        newComponents.add((ComponentConnector) childConnector);
                    } else if (!(childConnector instanceof AbstractExtensionConnector)) {
                        throw new IllegalStateException(Util.getConnectorString(childConnector)
                                + " is not a ComponentConnector nor an AbstractExtensionConnector");
                    }
                    if (childConnector.getParent() != parentConnector) {
                        childConnector.setParent(parentConnector);
                        result.parentChangedIds.add(childConnectorId);
                        // Not detached even if previously removed from
                        // parent
                        maybeDetached.remove(childConnectorId);
                    }
                }

                Profiler.leave("updateConnectorHierarchy find new connectors");

                // TODO This check should be done on the server side in
                // the future so the hierarchy update is only sent when
                // something actually has changed
                List<ServerConnector> oldChildren = parentConnector.getChildren();
                boolean actuallyChanged = !Util.collectionsEquals(oldChildren, newChildren);

                if (!actuallyChanged) {
                    return;
                }

                Profiler.enter("updateConnectorHierarchy handle HasComponentsConnector");

                if (parentConnector instanceof HasComponentsConnector) {
                    HasComponentsConnector ccc = (HasComponentsConnector) parentConnector;
                    List<ComponentConnector> oldComponents = ccc.getChildComponents();
                    if (!Util.collectionsEquals(oldComponents, newComponents)) {
                        // Fire change event if the hierarchy has
                        // changed
                        ConnectorHierarchyChangeEvent event = GWT.create(ConnectorHierarchyChangeEvent.class);
                        event.setOldChildren(oldComponents);
                        event.setConnector(parentConnector);
                        ccc.setChildComponents(newComponents);
                        result.events.add(event);
                    }
                } else if (!newComponents.isEmpty()) {
                    getLogger().severe("Hierachy claims " + Util.getConnectorString(parentConnector)
                            + " has component children even though it isn't a HasComponentsConnector");
                }

                Profiler.leave("updateConnectorHierarchy handle HasComponentsConnector");

                Profiler.enter("updateConnectorHierarchy setChildren");
                parentConnector.setChildren(newChildren);
                Profiler.leave("updateConnectorHierarchy setChildren");

                Profiler.enter("updateConnectorHierarchy find removed children");

                /*
                 * Find children removed from this parent and mark for
                 * removal unless they are already attached to some other
                 * parent.
                 */
                for (ServerConnector oldChild : oldChildren) {
                    if (oldChild.getParent() != parentConnector) {
                        // Ignore if moved to some other connector
                        continue;
                    }

                    if (!newChildren.contains(oldChild)) {
                        /*
                         * Consider child detached for now, will be cleared
                         * if it is later on added to some other parent.
                         */
                        maybeDetached.add(oldChild.getConnectorId());
                    }
                }

                Profiler.leave("updateConnectorHierarchy find removed children");
            } catch (final Throwable e) {
                getLogger().log(Level.SEVERE, "Error updating connector hierarchy", e);
            } finally {
                Profiler.leave("updateConnectorHierarchy hierarchy entry");
            }
        }

        private void recursivelyDetach(ServerConnector connector,
                JsArrayObject<ConnectorHierarchyChangeEvent> events, FastStringSet detachedConnectors) {
            detachedConnectors.add(connector.getConnectorId());

            /*
             * Reset state in an attempt to keep it consistent with the
             * hierarchy. No children and no parent is the initial situation
             * for the hierarchy, so changing the state to its initial value
             * is the closest we can get without data from the server.
             * #10151
             */
            String prefix = getClass().getSimpleName() + " ";
            Profiler.enter(prefix + "recursivelyDetach reset state");
            try {
                Profiler.enter(prefix + "recursivelyDetach reset state - getStateType");
                Type stateType = AbstractConnector.getStateType(connector);
                Profiler.leave(prefix + "recursivelyDetach reset state - getStateType");

                // Empty state instance to get default property values from
                Profiler.enter(prefix + "recursivelyDetach reset state - createInstance");
                Object defaultState = stateType.createInstance();
                Profiler.leave(prefix + "recursivelyDetach reset state - createInstance");

                if (connector instanceof AbstractConnector) {
                    // optimization as the loop setting properties is very
                    // slow, especially on IE8
                    replaceState((AbstractConnector) connector, defaultState);
                } else {
                    SharedState state = connector.getState();

                    Profiler.enter(prefix + "recursivelyDetach reset state - properties");
                    JsArrayObject<Property> properties = stateType.getPropertiesAsArray();
                    int size = properties.size();
                    for (int i = 0; i < size; i++) {
                        Property property = properties.get(i);
                        property.setValue(state, property.getValue(defaultState));
                    }
                    Profiler.leave(prefix + "recursivelyDetach reset state - properties");
                }
            } catch (NoDataException e) {
                throw new RuntimeException("Can't reset state for " + Util.getConnectorString(connector), e);
            } finally {
                Profiler.leave(prefix + "recursivelyDetach reset state");
            }

            Profiler.enter(prefix + "recursivelyDetach perform detach");
            /*
             * Recursively detach children to make sure they get
             * setParent(null) and hierarchy change events as needed.
             */
            for (ServerConnector child : connector.getChildren()) {
                /*
                 * Server doesn't send updated child data for removed
                 * connectors -> ignore child that still seems to be a child
                 * of this connector although it has been moved to some part
                 * of the hierarchy that is not detached.
                 */
                if (child.getParent() != connector) {
                    continue;
                }
                recursivelyDetach(child, events, detachedConnectors);
            }
            Profiler.leave(prefix + "recursivelyDetach perform detach");

            /*
             * Clear child list and parent
             */
            Profiler.enter(prefix + "recursivelyDetach clear children and parent");
            connector.setChildren(Collections.<ServerConnector>emptyList());
            connector.setParent(null);
            Profiler.leave(prefix + "recursivelyDetach clear children and parent");

            /*
             * Create an artificial hierarchy event for containers to give
             * it a chance to clean up after its children if it has any
             */
            Profiler.enter(prefix + "recursivelyDetach create hierarchy event");
            if (connector instanceof HasComponentsConnector) {
                HasComponentsConnector ccc = (HasComponentsConnector) connector;
                List<ComponentConnector> oldChildren = ccc.getChildComponents();
                if (!oldChildren.isEmpty()) {
                    /*
                     * HasComponentsConnector has a separate child component
                     * list that should also be cleared
                     */
                    ccc.setChildComponents(Collections.<ComponentConnector>emptyList());

                    // Create event and add it to the list of pending events
                    ConnectorHierarchyChangeEvent event = GWT.create(ConnectorHierarchyChangeEvent.class);
                    event.setConnector(connector);
                    event.setOldChildren(oldChildren);
                    events.add(event);
                }
            }
            Profiler.leave(prefix + "recursivelyDetach create hierarchy event");
        }

        private native void replaceState(AbstractConnector connector, Object defaultState)
        /*-{
        connector.@com.vaadin.client.ui.AbstractConnector::state = defaultState;
        }-*/;

        private void handleRpcInvocations(ValueMap json) {
            if (json.containsKey("rpc")) {
                Profiler.enter("handleRpcInvocations");

                getLogger().info(" * Performing server to client RPC calls");

                JsonArray rpcCalls = Util.jso2json(json.getJavaScriptObject("rpc"));

                int rpcLength = rpcCalls.length();
                for (int i = 0; i < rpcLength; i++) {
                    try {
                        JsonArray rpcCall = rpcCalls.getArray(i);
                        MethodInvocation invocation = getRpcManager().parseAndApplyInvocation(rpcCall,
                                connection);

                        if (onlyNoLayoutUpdates && !RpcManager.getMethod(invocation).isNoLayout()) {
                            onlyNoLayoutUpdates = false;
                        }

                    } catch (final Throwable e) {
                        getLogger().log(Level.SEVERE, "Error performing server to client RPC calls", e);
                    }
                }

                Profiler.leave("handleRpcInvocations");
            }
        }

    };
    ApplicationConfiguration.runWhenDependenciesLoaded(c);
}

From source file:com.vaadin.client.connectors.JavaScriptRendererConnector.java

License:Apache License

@Override
protected Renderer<JsonValue> createRenderer() {
    helper.ensureJavascriptInited();// ww  w.  ja  v a  2 s .  c  om

    if (!hasFunction("render")) {
        throw new RuntimeException(
                "JavaScriptRenderer " + helper.getInitFunctionName() + " must have a function named 'render'");
    }

    final boolean hasInit = hasFunction("init");
    final boolean hasDestroy = hasFunction("destroy");
    final boolean hasOnActivate = hasFunction("onActivate");
    final boolean hasGetConsumedEvents = hasFunction("getConsumedEvents");
    final boolean hasOnBrowserEvent = hasFunction("onBrowserEvent");

    return new ComplexRenderer<JsonValue>() {
        @Override
        public void render(RendererCellReference cell, JsonValue data) {
            render(helper.getConnectorWrapper(), getJsCell(cell), Util.json2jso(data));
        }

        private JavaScriptObject getJsCell(CellReference<?> cell) {
            updateCellReference(cellReferenceWrapper, cell);
            return cellReferenceWrapper;
        }

        public native void render(JavaScriptObject wrapper, JavaScriptObject cell, JavaScriptObject data)
        /*-{
        wrapper.render(cell, data);
        }-*/;

        @Override
        public void init(RendererCellReference cell) {
            if (hasInit) {
                init(helper.getConnectorWrapper(), getJsCell(cell));
            }
        }

        private native void init(JavaScriptObject wrapper, JavaScriptObject cell)
        /*-{
        wrapper.init(cell);
        }-*/;

        private native void updateCellReference(JavaScriptObject cellWrapper, CellReference<?> target)
        /*-{
        cellWrapper.target = target;
        }-*/;

        @Override
        public void destroy(RendererCellReference cell) {
            if (hasDestroy) {
                destory(helper.getConnectorWrapper(), getJsCell(cell));
            } else {
                super.destroy(cell);
            }
        }

        private native void destory(JavaScriptObject wrapper, JavaScriptObject cell)
        /*-{
        wrapper.destory(cell);
        }-*/;

        @Override
        public boolean onActivate(CellReference<?> cell) {
            if (hasOnActivate) {
                return onActivate(helper.getConnectorWrapper(), getJsCell(cell));
            } else {
                return super.onActivate(cell);
            }
        }

        private native boolean onActivate(JavaScriptObject wrapper, JavaScriptObject cell)
        /*-{
        return !!wrapper.onActivate(cell);
        }-*/;

        @Override
        public Collection<String> getConsumedEvents() {
            if (hasGetConsumedEvents) {
                JsArrayString events = getConsumedEvents(helper.getConnectorWrapper());

                ArrayList<String> list = new ArrayList<String>(events.length());
                for (int i = 0; i < events.length(); i++) {
                    list.add(events.get(i));
                }
                return list;
            } else {
                return super.getConsumedEvents();
            }
        }

        private native JsArrayString getConsumedEvents(JavaScriptObject wrapper)
        /*-{
        var rawEvents = wrapper.getConsumedEvents();
        var events = [];
        for(var i = 0; i < rawEvents.length; i++) {
          events[i] = ""+rawEvents[i];
        }
        return events;
        }-*/;

        @Override
        public boolean onBrowserEvent(CellReference<?> cell, NativeEvent event) {
            if (hasOnBrowserEvent) {
                return onBrowserEvent(helper.getConnectorWrapper(), getJsCell(cell), event);
            } else {
                return super.onBrowserEvent(cell, event);
            }
        }

        private native boolean onBrowserEvent(JavaScriptObject wrapper, JavaScriptObject cell,
                NativeEvent event)
        /*-{
        return !!wrapper.onBrowserEvent(cell, event);
        }-*/;
    };
}

From source file:com.vaadin.client.extensions.DropTargetExtensionConnector.java

License:Apache License

/**
 * Event handler for the {@code drop} event.
 *
 * @param event//w w  w  .  j  av a 2 s . c om
 *         browser event to be handled
 */
protected void onDrop(Event event) {
    NativeEvent nativeEvent = (NativeEvent) event;
    if (dropAllowed(nativeEvent)) {
        nativeEvent.preventDefault();
        nativeEvent.stopPropagation();

        // Initiate firing server side drop event
        JsArrayString typesJsArray = getTypes(nativeEvent.getDataTransfer());
        List<String> types = new ArrayList<>();
        Map<String, String> data = new HashMap<>();
        for (int i = 0; i < typesJsArray.length(); i++) {
            types.add(typesJsArray.get(i));
            data.put(typesJsArray.get(i), nativeEvent.getDataTransfer().getData(typesJsArray.get(i)));
        }

        getRpcProxy(DropTargetRpc.class).drop(types, data, getState().dropEffect,
                data.get(DragSourceExtensionConnector.DATA_TYPE_DRAG_SOURCE_ID));
    }

    removeTargetIndicator(getDropTargetElement());
}

From source file:com.vaadin.client.LayoutManager.java

License:Apache License

private void doLayout() {
    getLogger().info("Starting layout phase");
    Profiler.enter("LayoutManager phase init");

    FastStringMap<Integer> layoutCounts = FastStringMap.create();

    int passes = 0;
    Duration totalDuration = new Duration();

    ConnectorMap connectorMap = ConnectorMap.get(connection);

    JsArrayString dump = needsHorizontalLayout.dump();
    int dumpLength = dump.length();
    for (int i = 0; i < dumpLength; i++) {
        String layoutId = dump.get(i);
        currentDependencyTree.setNeedsHorizontalLayout(layoutId, true);
    }/*from  w  w w  .j av  a2 s.  co m*/

    dump = needsVerticalLayout.dump();
    dumpLength = dump.length();
    for (int i = 0; i < dumpLength; i++) {
        String layoutId = dump.get(i);
        currentDependencyTree.setNeedsVerticalLayout(layoutId, true);
    }
    needsHorizontalLayout = FastStringSet.create();
    needsVerticalLayout = FastStringSet.create();

    dump = needsMeasure.dump();
    dumpLength = dump.length();
    for (int i = 0; i < dumpLength; i++) {
        ServerConnector connector = connectorMap.getConnector(dump.get(i));
        if (connector != null) {
            currentDependencyTree.setNeedsMeasure((ComponentConnector) connector, true);
        }
    }
    needsMeasure = FastStringSet.create();

    measureNonConnectors();

    Profiler.leave("LayoutManager phase init");

    while (true) {
        Profiler.enter("Layout pass");
        passes++;

        performBrowserLayoutHacks();

        Profiler.enter("Layout measure connectors");
        int measuredConnectorCount = measureConnectors(currentDependencyTree, everythingNeedsMeasure);
        Profiler.leave("Layout measure connectors");

        everythingNeedsMeasure = false;
        if (measuredConnectorCount == 0) {
            getLogger().info("No more changes in pass " + passes);
            Profiler.leave("Layout pass");
            break;
        }

        int firedListeners = 0;
        if (!listenersToFire.isEmpty()) {
            firedListeners = listenersToFire.size();
            Profiler.enter("Layout fire resize events");
            for (Element element : listenersToFire) {
                Collection<ElementResizeListener> listeners = elementResizeListeners.get(element);
                if (listeners != null) {
                    Profiler.enter("Layout fire resize events - listeners not null");
                    Profiler.enter("ElementResizeListener.onElementResize copy list");
                    ElementResizeListener[] array = listeners
                            .toArray(new ElementResizeListener[listeners.size()]);
                    Profiler.leave("ElementResizeListener.onElementResize copy list");
                    ElementResizeEvent event = new ElementResizeEvent(this, element);
                    for (ElementResizeListener listener : array) {
                        try {
                            String key = null;
                            if (Profiler.isEnabled()) {
                                Profiler.enter("ElementResizeListener.onElementResize construct profiler key");
                                key = "ElementResizeListener.onElementResize for "
                                        + listener.getClass().getSimpleName();
                                Profiler.leave("ElementResizeListener.onElementResize construct profiler key");
                                Profiler.enter(key);
                            }

                            listener.onElementResize(event);
                            if (Profiler.isEnabled()) {
                                Profiler.leave(key);
                            }
                        } catch (RuntimeException e) {
                            getLogger().log(Level.SEVERE, "Error in resize listener", e);
                        }
                    }
                    Profiler.leave("Layout fire resize events - listeners not null");
                }
            }
            listenersToFire.clear();

            Profiler.leave("Layout fire resize events");
        }

        Profiler.enter("LayoutManager handle ManagedLayout");

        FastStringSet updatedSet = FastStringSet.create();

        int layoutCount = 0;
        while (currentDependencyTree.hasHorizontalConnectorToLayout()
                || currentDependencyTree.hasVerticaConnectorToLayout()) {

            JsArrayString layoutTargets = currentDependencyTree.getHorizontalLayoutTargetsJsArray();
            int length = layoutTargets.length();
            for (int i = 0; i < length; i++) {
                ManagedLayout layout = (ManagedLayout) connectorMap.getConnector(layoutTargets.get(i));
                if (layout instanceof DirectionalManagedLayout) {
                    currentDependencyTree.markAsHorizontallyLayouted(layout);
                    DirectionalManagedLayout cl = (DirectionalManagedLayout) layout;
                    try {
                        String key = null;
                        if (Profiler.isEnabled()) {
                            key = "layoutHorizontally() for " + cl.getClass().getSimpleName();
                            Profiler.enter(key);
                        }

                        cl.layoutHorizontally();
                        layoutCount++;

                        if (Profiler.isEnabled()) {
                            Profiler.leave(key);
                        }
                    } catch (RuntimeException e) {
                        getLogger().log(Level.SEVERE, "Error in ManagedLayout handling", e);
                    }
                    countLayout(layoutCounts, cl);
                } else {
                    currentDependencyTree.markAsHorizontallyLayouted(layout);
                    currentDependencyTree.markAsVerticallyLayouted(layout);
                    SimpleManagedLayout rr = (SimpleManagedLayout) layout;
                    try {
                        String key = null;
                        if (Profiler.isEnabled()) {
                            key = "layout() for " + rr.getClass().getSimpleName();
                            Profiler.enter(key);
                        }

                        rr.layout();
                        layoutCount++;

                        if (Profiler.isEnabled()) {
                            Profiler.leave(key);
                        }
                    } catch (RuntimeException e) {
                        getLogger().log(Level.SEVERE, "Error in SimpleManagedLayout (horizontal) handling", e);

                    }
                    countLayout(layoutCounts, rr);
                }
                if (debugLogging) {
                    updatedSet.add(layout.getConnectorId());
                }
            }

            layoutTargets = currentDependencyTree.getVerticalLayoutTargetsJsArray();
            length = layoutTargets.length();
            for (int i = 0; i < length; i++) {
                ManagedLayout layout = (ManagedLayout) connectorMap.getConnector(layoutTargets.get(i));
                if (layout instanceof DirectionalManagedLayout) {
                    currentDependencyTree.markAsVerticallyLayouted(layout);
                    DirectionalManagedLayout cl = (DirectionalManagedLayout) layout;
                    try {
                        String key = null;
                        if (Profiler.isEnabled()) {
                            key = "layoutVertically() for " + cl.getClass().getSimpleName();
                            Profiler.enter(key);
                        }

                        cl.layoutVertically();
                        layoutCount++;

                        if (Profiler.isEnabled()) {
                            Profiler.leave(key);
                        }
                    } catch (RuntimeException e) {
                        getLogger().log(Level.SEVERE, "Error in DirectionalManagedLayout handling", e);
                    }
                    countLayout(layoutCounts, cl);
                } else {
                    currentDependencyTree.markAsHorizontallyLayouted(layout);
                    currentDependencyTree.markAsVerticallyLayouted(layout);
                    SimpleManagedLayout rr = (SimpleManagedLayout) layout;
                    try {
                        String key = null;
                        if (Profiler.isEnabled()) {
                            key = "layout() for " + rr.getClass().getSimpleName();
                            Profiler.enter(key);
                        }

                        rr.layout();
                        layoutCount++;

                        if (Profiler.isEnabled()) {
                            Profiler.leave(key);
                        }
                    } catch (RuntimeException e) {
                        getLogger().log(Level.SEVERE, "Error in SimpleManagedLayout (vertical) handling", e);
                    }
                    countLayout(layoutCounts, rr);
                }
                if (debugLogging) {
                    updatedSet.add(layout.getConnectorId());
                }
            }
        }

        Profiler.leave("LayoutManager handle ManagedLayout");

        if (debugLogging) {
            JsArrayString changedCids = updatedSet.dump();

            StringBuilder b = new StringBuilder("  ");
            b.append(changedCids.length());
            b.append(" requestLayout invocations ");
            if (changedCids.length() < 30) {
                for (int i = 0; i < changedCids.length(); i++) {
                    if (i != 0) {
                        b.append(", ");
                    } else {
                        b.append(": ");
                    }
                    String connectorString = changedCids.get(i);
                    if (changedCids.length() < 10) {
                        ServerConnector connector = ConnectorMap.get(connection).getConnector(connectorString);
                        connectorString = Util.getConnectorString(connector);
                    }
                    b.append(connectorString);
                }
            }
            getLogger().info(b.toString());
        }

        Profiler.leave("Layout pass");

        getLogger().info("Pass " + passes + " measured " + measuredConnectorCount + " elements, fired "
                + firedListeners + " listeners and did " + layoutCount + " layouts.");

        if (passes > 100) {
            getLogger().severe(LOOP_ABORT_MESSAGE);
            if (ApplicationConfiguration.isDebugMode()) {
                VNotification
                        .createNotification(VNotification.DELAY_FOREVER,
                                connection.getUIConnector().getWidget())
                        .show(LOOP_ABORT_MESSAGE, VNotification.CENTERED, "error");
            }
            break;
        }
    }

    Profiler.enter("layout PostLayoutListener");
    JsArrayObject<ComponentConnector> componentConnectors = connectorMap.getComponentConnectorsAsJsArray();
    int size = componentConnectors.size();
    for (int i = 0; i < size; i++) {
        ComponentConnector connector = componentConnectors.get(i);
        if (connector instanceof PostLayoutListener) {
            String key = null;
            if (Profiler.isEnabled()) {
                key = "layout PostLayoutListener for " + connector.getClass().getSimpleName();
                Profiler.enter(key);
            }

            ((PostLayoutListener) connector).postLayout();

            if (Profiler.isEnabled()) {
                Profiler.leave(key);
            }
        }
    }
    Profiler.leave("layout PostLayoutListener");

    cleanMeasuredSizes();

    getLogger().info("Total layout phase time: " + totalDuration.elapsedMillis() + "ms");
}

From source file:com.vaadin.client.LayoutManager.java

License:Apache License

private int measureConnectors(LayoutDependencyTree layoutDependencyTree, boolean measureAll) {
    Profiler.enter("Layout overflow fix handling");
    JsArrayString pendingOverflowConnectorsIds = pendingOverflowFixes.dump();
    int pendingOverflowCount = pendingOverflowConnectorsIds.length();
    ConnectorMap connectorMap = ConnectorMap.get(connection);
    if (pendingOverflowCount > 0) {
        HashMap<Element, String> originalOverflows = new HashMap<Element, String>();

        FastStringSet delayedOverflowFixes = FastStringSet.create();

        // First set overflow to hidden (and save previous value so it can
        // be restored later)
        for (int i = 0; i < pendingOverflowCount; i++) {
            String connectorId = pendingOverflowConnectorsIds.get(i);
            ComponentConnector componentConnector = (ComponentConnector) connectorMap.getConnector(connectorId);

            if (delayOverflowFix(componentConnector)) {
                delayedOverflowFixes.add(connectorId);
                continue;
            }/*  w  w  w .j a  v  a2s . com*/

            if (debugLogging) {
                getLogger().info("Doing overflow fix for " + Util.getConnectorString(componentConnector)
                        + " in " + Util.getConnectorString(componentConnector.getParent()));
            }
            Profiler.enter("Overflow fix apply");

            Element parentElement = componentConnector.getWidget().getElement().getParentElement();
            Style style = parentElement.getStyle();
            String originalOverflow = style.getOverflow();

            if (originalOverflow != null && !originalOverflows.containsKey(parentElement)) {
                // Store original value for restore, but only the first time
                // the value is changed
                originalOverflows.put(parentElement, originalOverflow);
            }

            style.setOverflow(Overflow.HIDDEN);
            Profiler.leave("Overflow fix apply");
        }

        pendingOverflowFixes.removeAll(delayedOverflowFixes);

        JsArrayString remainingOverflowFixIds = pendingOverflowFixes.dump();
        int remainingCount = remainingOverflowFixIds.length();

        Profiler.enter("Overflow fix reflow");
        // Then ensure all scrolling elements are reflowed by measuring
        for (int i = 0; i < remainingCount; i++) {
            ComponentConnector componentConnector = (ComponentConnector) connectorMap
                    .getConnector(remainingOverflowFixIds.get(i));
            componentConnector.getWidget().getElement().getParentElement().getOffsetHeight();
        }
        Profiler.leave("Overflow fix reflow");

        Profiler.enter("Overflow fix restore");
        // Finally restore old overflow value and update bookkeeping
        for (int i = 0; i < remainingCount; i++) {
            String connectorId = remainingOverflowFixIds.get(i);
            ComponentConnector componentConnector = (ComponentConnector) connectorMap.getConnector(connectorId);
            Element parentElement = componentConnector.getWidget().getElement().getParentElement();
            parentElement.getStyle().setProperty("overflow", originalOverflows.get(parentElement));

            layoutDependencyTree.setNeedsMeasure(componentConnector, true);
        }
        Profiler.leave("Overflow fix restore");

        if (!pendingOverflowFixes.isEmpty()) {
            getLogger().info("Did overflow fix for " + remainingCount + " elements");
        }
        pendingOverflowFixes = delayedOverflowFixes;
    }
    Profiler.leave("Layout overflow fix handling");

    int measureCount = 0;
    if (measureAll) {
        Profiler.enter("Layout measureAll");
        JsArrayObject<ComponentConnector> allConnectors = connectorMap.getComponentConnectorsAsJsArray();
        int size = allConnectors.size();

        // Find connectors that should actually be measured
        JsArrayObject<ComponentConnector> connectors = JsArrayObject.createArray().cast();
        for (int i = 0; i < size; i++) {
            ComponentConnector candidate = allConnectors.get(i);
            if (!Util.shouldSkipMeasurementOfConnector(candidate)
                    && needsMeasure(candidate.getWidget().getElement())) {
                connectors.add(candidate);
            }
        }

        int connectorCount = connectors.size();
        for (int i = 0; i < connectorCount; i++) {
            measureConnector(connectors.get(i));
        }
        for (int i = 0; i < connectorCount; i++) {
            layoutDependencyTree.setNeedsMeasure(connectors.get(i), false);
        }
        measureCount += connectorCount;

        Profiler.leave("Layout measureAll");
    }

    Profiler.enter("Layout measure from tree");
    while (layoutDependencyTree.hasConnectorsToMeasure()) {
        JsArrayString measureTargets = layoutDependencyTree.getMeasureTargetsJsArray();
        int length = measureTargets.length();
        for (int i = 0; i < length; i++) {
            ComponentConnector connector = (ComponentConnector) connectorMap
                    .getConnector(measureTargets.get(i));
            measureConnector(connector);
            measureCount++;
        }
        for (int i = 0; i < length; i++) {
            ComponentConnector connector = (ComponentConnector) connectorMap
                    .getConnector(measureTargets.get(i));
            layoutDependencyTree.setNeedsMeasure(connector, false);
        }
    }
    Profiler.leave("Layout measure from tree");

    return measureCount;
}