Example usage for java.util.concurrent ArrayBlockingQueue ArrayBlockingQueue

List of usage examples for java.util.concurrent ArrayBlockingQueue ArrayBlockingQueue

Introduction

In this page you can find the example usage for java.util.concurrent ArrayBlockingQueue ArrayBlockingQueue.

Prototype

public ArrayBlockingQueue(int capacity) 

Source Link

Document

Creates an ArrayBlockingQueue with the given (fixed) capacity and default access policy.

Usage

From source file:com.orange.mmp.message.jms.JMSMessageBroker.java

@SuppressWarnings("unchecked")
public void initialize() throws MMPException {
    //Initialize the Listeners list
    this.messageListeners = Collections.synchronizedList(new ArrayList<MessageListener>());
    //Initialize the module message listeners configuration cache
    this.moduleListenersCache = new ConcurrentHashMap<Class, MessageListener>();

    this.syncListenerPool = new ArrayBlockingQueue<JMSSyncMessageListener>(this.maxSynchronousListeners);
    try {/*w w  w . j  a  v  a 2  s .  co  m*/
        for (int i = 0; i < this.maxSynchronousListeners; i++) {
            this.syncListenerPool.put(new JMSSyncMessageListener());
        }
    } catch (InterruptedException e) {
        throw new MMPMessageException(e);
    }

    //Initialize Listeners Cache
    this.messageListenersMap = new ConcurrentHashMap<Serializable, MessageListener>();

    //Get the ModuleContainer and add itself as a ModuleObserver
    ModuleContainerFactory.getInstance().getModuleContainer().registerModuleObserver(this);
}

From source file:org.pixmob.freemobile.netstat.MonitorService.java

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override/*from   ww  w . j  a v  a  2 s  .  c  o  m*/
public void onCreate() {
    super.onCreate();

    pm = (PowerManager) getSystemService(POWER_SERVICE);
    tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);

    prefs = getSharedPreferences(SP_NAME, MODE_PRIVATE);
    prefs.registerOnSharedPreferenceChangeListener(this);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        final int largeIconWidth = getResources()
                .getDimensionPixelSize(android.R.dimen.notification_large_icon_width);
        final int largeIconHeight = getResources()
                .getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
        if ((largeIconWidth > 0) && (largeIconHeight > 0)) {
            Bitmap freeLargeIconTmp = BitmapFactory.decodeResource(getResources(),
                    R.drawable.ic_stat_notify_service_free_large);
            if ((freeLargeIconTmp != null) && (freeLargeIconTmp.getWidth() > 0)
                    && (freeLargeIconTmp.getHeight() > 0)) {
                freeLargeIcon = Bitmap.createScaledBitmap(freeLargeIconTmp, largeIconWidth, largeIconHeight,
                        true);
            }

            Bitmap freeFemtoLargeIconTmp = BitmapFactory.decodeResource(getResources(),
                    R.drawable.ic_stat_notify_service_free_femto_large);
            if ((freeFemtoLargeIconTmp != null) && (freeFemtoLargeIconTmp.getHeight() > 0)
                    && (freeFemtoLargeIconTmp.getWidth() > 0)) {
                freeFemtoLargeIcon = Bitmap.createScaledBitmap(freeFemtoLargeIconTmp, largeIconWidth,
                        largeIconHeight, true);
            }

            Bitmap orangeLargeIconTmp = BitmapFactory.decodeResource(getResources(),
                    R.drawable.ic_stat_notify_service_orange_large);
            if ((orangeLargeIconTmp != null) && (orangeLargeIconTmp.getHeight() > 0)
                    && (orangeLargeIconTmp.getWidth() > 0)) {
                orangeLargeIcon = Bitmap.createScaledBitmap(orangeLargeIconTmp, largeIconWidth, largeIconHeight,
                        true);
            }
        }
    }

    // Initialize and start a worker thread for inserting rows into the
    // application database.
    final Context c = getApplicationContext();
    pendingInsert = new ArrayBlockingQueue<>(8);
    new PendingInsertWorker(c, pendingInsert).start();

    // This intent is fired when the application notification is clicked.
    openUIPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_NOTIFICATION),
            PendingIntent.FLAG_CANCEL_CURRENT);

    // This intent is only available as a Jelly Bean notification action in
    // order to open network operator settings.
    Intent networkSettingsIntent = IntentFactory.networkOperatorSettings(this);
    if (networkSettingsIntent != null) {
        networkOperatorSettingsPendingIntent = PendingIntent.getActivity(this, 0, networkSettingsIntent,
                PendingIntent.FLAG_CANCEL_CURRENT);
    }
    Intent wirelessSettingsIntent = IntentFactory.wirelessSettings(this);
    if (wirelessSettingsIntent != null) {
        wirelessSettingsPendingIntent = PendingIntent.getActivity(this, 0, wirelessSettingsIntent,
                PendingIntent.FLAG_CANCEL_CURRENT);
    }

    // Watch screen light: is the screen on?
    screenMonitor = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            updateEventDatabase();
        }
    };

    final IntentFilter screenIntentFilter = new IntentFilter();
    screenIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
    screenIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
    registerReceiver(screenMonitor, screenIntentFilter);

    // Watch Wi-Fi connections.
    connectionMonitor = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (onConnectivityUpdated()) {
                updateEventDatabase();
            }
        }
    };

    final IntentFilter connectionIntentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    registerReceiver(connectionMonitor, connectionIntentFilter);

    // Watch mobile connections.
    phoneMonitor = new PhoneStateListener() {
        @Override
        public void onDataConnectionStateChanged(int state, int networkType) {
            updateService();
        }

        @Override
        public void onServiceStateChanged(ServiceState serviceState) {
            if (stopServiceIfSimOperatorIsNotFreeMobile())
                return;

            mobileNetworkConnected = (serviceState != null)
                    && (serviceState.getState() == ServiceState.STATE_IN_SERVICE);

            updateService();
        }

        @Override
        public void onCellInfoChanged(List<CellInfo> cellInfo) {
            updateService();
        }

        private void updateService() {
            if (tm != null) { // Fix NPE - found by Acralyzer
                mobileNetworkType = tm.getNetworkType(); //update the network type to have the latest
            }
            final int phoneStateUpdated = onPhoneStateUpdated();
            if (phoneStateUpdated >= 0)
                updateEventDatabase();

            updateNotification(true, phoneStateUpdated == 1);
        }
    };
    int events = PhoneStateListener.LISTEN_SERVICE_STATE | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
        events |= PhoneStateListener.LISTEN_CELL_INFO;

    tm.listen(phoneMonitor, events);

    // Watch battery level.
    batteryMonitor = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            updateEventDatabase();
        }
    };

    batteryIntentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    registerReceiver(batteryMonitor, batteryIntentFilter);

    shutdownMonitor = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            onDeviceShutdown();
        }
    };
    final IntentFilter shutdownIntentFilter = new IntentFilter();
    shutdownIntentFilter.addAction(Intent.ACTION_SHUTDOWN);
    // HTC devices use a different Intent action:
    // http://stackoverflow.com/q/5076410/422906
    shutdownIntentFilter.addAction("android.intent.action.QUICKBOOT_POWEROFF");
    registerReceiver(shutdownMonitor, shutdownIntentFilter);

    if (prefs.getBoolean(SP_KEY_ENABLE_AUTO_RESTART_SERVICE, false) && Arrays
            .asList(ANDROID_VERSIONS_ALLOWED_TO_AUTO_RESTART_SERVICE).contains(Build.VERSION.RELEASE)) {
        // Kitkat and JellyBean auto-kill service workaround
        // http://stackoverflow.com/a/20735519/1527491
        ensureServiceStaysRunning();
    }
}

From source file:org.alfresco.repo.batch.BatchProcessor.java

/**
 * Invokes the worker for each entry in the collection, managing transactions and collating success / failure
 * information./*from   w w w.j a va  2  s . co  m*/
 * 
 * @param worker
 *            the worker
 * @param splitTxns
 *            Can the modifications to Alfresco be split across multiple transactions for maximum performance? If
 *            <code>true</code>, worker invocations are isolated in separate transactions in batches for
 *            increased performance. If <code>false</code>, all invocations are performed in the current
 *            transaction. This is required if calling synchronously (e.g. in response to an authentication event in
 *            the same transaction).
 * @return the number of invocations
 */
@SuppressWarnings("serial")
public int process(final BatchProcessWorker<T> worker, final boolean splitTxns) {
    int count = workProvider.getTotalEstimatedWorkSize();
    synchronized (this) {
        this.startTime = new Date();
        if (this.logger.isInfoEnabled()) {
            if (count >= 0) {
                this.logger.info(getProcessName() + ": Commencing batch of " + count + " entries");
            } else {
                this.logger.info(getProcessName() + ": Commencing batch");

            }
        }
    }

    // Create a thread pool executor with the specified number of threads and a finite blocking queue of jobs
    ExecutorService executorService = splitTxns && this.workerThreads > 1
            ? new ThreadPoolExecutor(this.workerThreads, this.workerThreads, 0L, TimeUnit.MILLISECONDS,
                    new ArrayBlockingQueue<Runnable>(this.workerThreads * this.batchSize * 10) {
                        // Add blocking behaviour to work queue
                        @Override
                        public boolean offer(Runnable o) {
                            try {
                                put(o);
                            } catch (InterruptedException e) {
                                return false;
                            }
                            return true;
                        }

                    }, threadFactory)
            : null;
    try {
        Iterator<T> iterator = new WorkProviderIterator<T>(this.workProvider);
        int id = 0;
        List<T> batch = new ArrayList<T>(this.batchSize);
        while (iterator.hasNext()) {
            batch.add(iterator.next());
            boolean hasNext = iterator.hasNext();
            if (batch.size() >= this.batchSize || !hasNext) {
                final TxnCallback callback = new TxnCallback(id++, worker, batch, splitTxns);
                if (hasNext) {
                    batch = new ArrayList<T>(this.batchSize);
                }

                if (executorService == null) {
                    callback.run();
                } else {
                    executorService.execute(callback);
                }
            }
        }
        return count;
    } finally {
        if (executorService != null) {
            executorService.shutdown();
            try {
                executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
            }
        }
        synchronized (this) {
            reportProgress(true);
            this.endTime = new Date();
            if (this.logger.isInfoEnabled()) {
                if (count >= 0) {
                    this.logger.info(getProcessName() + ": Completed batch of " + count + " entries");
                } else {
                    this.logger.info(getProcessName() + ": Completed batch");

                }
            }
            if (this.totalErrors > 0 && this.logger.isErrorEnabled()) {
                this.logger.error(
                        getProcessName() + ": " + this.totalErrors
                                + " error(s) detected. Last error from entry \"" + this.lastErrorEntryId + "\"",
                        this.lastError);
            }
        }
    }
}

From source file:eu.edisonproject.training.wsd.Wikidata.java

private Map<CharSequence, List<CharSequence>> getCategories(Set<Term> terms)
        throws MalformedURLException, InterruptedException, ExecutionException {
    Map<CharSequence, List<CharSequence>> cats = new HashMap<>();

    if (terms.size() > 0) {
        int maxT = 2;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue(maxT);
        ExecutorService pool = new ThreadPoolExecutor(maxT, maxT, 500L, TimeUnit.MICROSECONDS, workQueue);

        //            ExecutorService pool = new ThreadPoolExecutor(maxT, maxT,
        //                    5000L, TimeUnit.MILLISECONDS,
        //                    new ArrayBlockingQueue<>(maxT, true), new ThreadPoolExecutor.CallerRunsPolicy());
        Set<Future<Map<CharSequence, List<CharSequence>>>> set1 = new HashSet<>();
        String prop = "P910";
        for (Term t : terms) {
            URL url = new URL(
                    PAGE + "?action=wbgetclaims&format=json&props=&property=" + prop + "&entity=" + t.getUid());
            Logger.getLogger(Wikidata.class.getName()).log(Level.FINE, url.toString());
            WikiRequestor req = new WikiRequestor(url, t.getUid().toString(), 1);
            Future<Map<CharSequence, List<CharSequence>>> future = pool.submit(req);
            set1.add(future);/*from w ww .  j av  a 2  s  .  c  om*/
        }
        pool.shutdown();

        Map<CharSequence, List<CharSequence>> map = new HashMap<>();
        for (Future<Map<CharSequence, List<CharSequence>>> future : set1) {
            while (!future.isDone()) {
                //                Logger.getLogger(Wikipedia.class.getName()).log(Level.INFO, "Task is not completed yet....");
                Thread.currentThread().sleep(10);
            }
            Map<CharSequence, List<CharSequence>> c = future.get();
            if (c != null) {
                map.putAll(c);
            }
        }
        workQueue = new ArrayBlockingQueue(maxT);
        pool = new ThreadPoolExecutor(maxT, maxT, 500L, TimeUnit.MICROSECONDS, workQueue);

        //            pool = new ThreadPoolExecutor(maxT, maxT,
        //                    5000L, TimeUnit.MILLISECONDS,
        //                    new ArrayBlockingQueue<>(maxT, true), new ThreadPoolExecutor.CallerRunsPolicy());
        Set<Future<Map<CharSequence, List<CharSequence>>>> set2 = new HashSet<>();
        for (Term t : terms) {
            List<CharSequence> catIDs = map.get(t.getUid());
            for (CharSequence catID : catIDs) {
                URL url = new URL(
                        PAGE + "?action=wbgetentities&format=json&props=labels&languages=en&ids=" + catID);
                Logger.getLogger(Wikidata.class.getName()).log(Level.FINE, url.toString());
                WikiRequestor req = new WikiRequestor(url, t.getUid().toString(), 2);
                Future<Map<CharSequence, List<CharSequence>>> future = pool.submit(req);
                set2.add(future);
            }
        }
        pool.shutdown();

        for (Future<Map<CharSequence, List<CharSequence>>> future : set2) {
            while (!future.isDone()) {
                //                Logger.getLogger(Wikipedia.class.getName()).log(Level.INFO, "Task is not completed yet....");
                Thread.currentThread().sleep(10);
            }
            Map<CharSequence, List<CharSequence>> c = future.get();
            if (c != null) {
                cats.putAll(c);
            }
        }
    }

    return cats;
}

From source file:com.indeed.lsmtree.recordcache.PersistentRecordCache.java

/**
 * Performs lookup for multiple keys and returns a streaming iterator to results.
 * Each element in the iterator is one of
 *  (1) an exception associated with a single lookup
 *  (2) a key value tuple//from ww  w .  j  a  va 2s . c  o m
 *
 * @param keys      lookup keys
 * @param progress  (optional) an AtomicInteger for tracking progress
 * @param skipped   (optional) an AtomicInteger for tracking missing keys
 * @return          iterator of lookup results
 */
public Iterator<Either<Exception, P2<K, V>>> getStreaming(final @Nonnull Iterator<K> keys,
        final @Nullable AtomicInteger progress, final @Nullable AtomicInteger skipped) {
    log.info("starting store lookups");
    LongArrayList addressList = new LongArrayList();
    int notFound = 0;
    while (keys.hasNext()) {
        final K key = keys.next();
        final Long address;
        try {
            address = index.get(key);
        } catch (IOException e) {
            log.error("error", e);
            return Iterators.singletonIterator(Left.<Exception, P2<K, V>>of(new IndexReadException(e)));
        }
        if (address != null) {
            addressList.add(address);
        } else {
            notFound++;
        }
    }
    if (progress != null)
        progress.addAndGet(notFound);
    if (skipped != null)
        skipped.addAndGet(notFound);
    log.info("store lookups complete, sorting addresses");

    final long[] addresses = addressList.elements();
    Arrays.sort(addresses, 0, addressList.size());

    log.info("initializing store lookup iterator");
    final BlockingQueue<Runnable> taskQueue = new ArrayBlockingQueue<Runnable>(100);
    final Iterator<List<Long>> iterable = Iterators.partition(addressList.iterator(), 1000);
    final ExecutorService primerThreads = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, taskQueue,
            new NamedThreadFactory("store priming thread", true, log), new RejectedExecutionHandler() {
                @Override
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                    try {
                        taskQueue.put(r);
                    } catch (InterruptedException e) {
                        log.error("error", e);
                        throw new RuntimeException(e);
                    }
                }
            });
    final BlockingQueue<List<Either<Exception, P2<K, V>>>> completionQueue = new ArrayBlockingQueue<List<Either<Exception, P2<K, V>>>>(
            10);
    final AtomicLong runningTasks = new AtomicLong(0);
    final AtomicBoolean taskSubmitterRunning = new AtomicBoolean(true);

    new Thread(new Runnable() {
        @Override
        public void run() {
            while (iterable.hasNext()) {
                runningTasks.incrementAndGet();
                final List<Long> addressesSublist = iterable.next();
                primerThreads.submit(new FutureTask<List<Either<Exception, P2<K, V>>>>(
                        new RecordLookupTask(addressesSublist)) {
                    @Override
                    protected void done() {
                        try {
                            final List<Either<Exception, P2<K, V>>> results = get();
                            if (progress != null) {
                                progress.addAndGet(results.size());
                            }
                            completionQueue.put(results);
                        } catch (InterruptedException e) {
                            log.error("error", e);
                            throw new RuntimeException(e);
                        } catch (ExecutionException e) {
                            log.error("error", e);
                            throw new RuntimeException(e);
                        }
                    }
                });
            }
            taskSubmitterRunning.set(false);
        }
    }, "RecordLookupTaskSubmitterThread").start();

    return new Iterator<Either<Exception, P2<K, V>>>() {

        Iterator<Either<Exception, P2<K, V>>> currentIterator;

        @Override
        public boolean hasNext() {
            if (currentIterator != null && currentIterator.hasNext())
                return true;
            while (taskSubmitterRunning.get() || runningTasks.get() > 0) {
                try {
                    final List<Either<Exception, P2<K, V>>> list = completionQueue.poll(1, TimeUnit.SECONDS);
                    if (list != null) {
                        log.debug("remaining: " + runningTasks.decrementAndGet());
                        currentIterator = list.iterator();
                        if (currentIterator.hasNext())
                            return true;
                    }
                } catch (InterruptedException e) {
                    log.error("error", e);
                    throw new RuntimeException(e);
                }
            }
            primerThreads.shutdown();
            return false;
        }

        @Override
        public Either<Exception, P2<K, V>> next() {
            return currentIterator.next();
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    };
}

From source file:org.openmrs.module.openconceptlab.updater.Updater.java

private ThreadPoolExecutor newRunner() {
    return new ThreadPoolExecutor(0, THREAD_POOL_SIZE, 60, TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(THREAD_POOL_SIZE / 2), new RejectedExecutionHandler() {

                @Override//from   www .  ja  v a  2 s . co  m
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                    try {
                        executor.getQueue().put(r);
                    } catch (InterruptedException e) {
                        throw new RejectedExecutionException("Work discarded", e);
                    }
                }
            });
}

From source file:io.teak.sdk.TeakNotification.java

/**
 * Schedules a push notification for some time in the future.
 *
 * @param creativeId     The identifier of the notification in the Teak dashboard (will create if not found).
 * @param defaultMessage The default message to send, may be over-ridden in the dashboard.
 * @param delayInSeconds The delay in seconds from now to send the notification.
 * @return The identifier of the scheduled notification (see {@link TeakNotification#cancelNotification(String)} or null.
 *//* w  w  w .j  a v a 2  s. c om*/
@SuppressWarnings("unused")
public static FutureTask<String> scheduleNotification(final String creativeId, final String defaultMessage,
        final long delayInSeconds) {
    if (!Teak.isEnabled()) {
        Log.e(LOG_TAG, "Teak is disabled, ignoring scheduleNotification().");
        return null;
    }

    if (creativeId == null || creativeId.isEmpty()) {
        Log.e(LOG_TAG, "creativeId cannot be null or empty");
        return null;
    }

    if (defaultMessage == null || defaultMessage.isEmpty()) {
        Log.e(LOG_TAG, "defaultMessage cannot be null or empty");
        return null;
    }

    final ArrayBlockingQueue<String> q = new ArrayBlockingQueue<>(1);
    final FutureTask<String> ret = new FutureTask<>(new Callable<String>() {
        public String call() {
            try {
                return q.take();
            } catch (InterruptedException e) {
                Log.e(LOG_TAG, Log.getStackTraceString(e));
            }
            return null;
        }
    });

    Session.whenUserIdIsReadyRun(new Session.SessionRunnable() {
        @Override
        public void run(Session session) {
            HashMap<String, Object> payload = new HashMap<>();
            payload.put("identifier", creativeId);
            payload.put("message", defaultMessage);
            payload.put("offset", delayInSeconds);

            new Request("/me/local_notify.json", payload, session) {
                @Override
                protected void done(int responseCode, String responseBody) {
                    try {
                        JSONObject response = new JSONObject(responseBody);
                        if (response.getString("status").equals("ok")) {
                            q.offer(response.getJSONObject("event").getString("id"));
                        } else {
                            q.offer("");
                        }
                    } catch (Exception ignored) {
                        q.offer("");
                    }

                    ret.run();
                }
            }.run();
        }
    });
    return ret;
}

From source file:com.streamsets.pipeline.stage.origin.salesforce.ForceSource.java

@Override
protected List<ConfigIssue> init() {
    // Validate configuration values and open any required resources.
    List<ConfigIssue> issues = super.init();
    Optional.ofNullable(conf.init(getContext(), CONF_PREFIX)).ifPresent(issues::addAll);

    if (!conf.subscribeToStreaming && !conf.queryExistingData) {
        issues.add(getContext().createConfigIssue(Groups.FORCE.name(),
                ForceConfigBean.CONF_PREFIX + "queryExistingData", Errors.FORCE_00,
                "You must query existing data, subscribe for notifications, or both!"));
    }/* w  w  w  .  ja  va2 s  .  com*/

    if (conf.queryExistingData && conf.subscriptionType == SubscriptionType.PLATFORM_EVENT) {
        issues.add(getContext().createConfigIssue(Groups.FORCE.name(),
                ForceConfigBean.CONF_PREFIX + "queryExistingData", Errors.FORCE_00,
                "You cannot both query existing data and subscribe to a Platform Event!"));
    }

    if (conf.queryExistingData) {
        if (conf.usePKChunking) {
            conf.offsetColumn = ID;
        }

        if (!conf.disableValidation) {
            SOQLParser.StatementContext statementContext = ForceUtils.getStatementContext(conf.soqlQuery);
            SOQLParser.ConditionExpressionsContext conditionExpressions = statementContext
                    .conditionExpressions();
            SOQLParser.FieldOrderByListContext fieldOrderByList = statementContext.fieldOrderByList();

            if (conf.usePKChunking) {
                if (fieldOrderByList != null) {
                    issues.add(getContext().createConfigIssue(Groups.QUERY.name(),
                            ForceConfigBean.CONF_PREFIX + "soqlQuery", Errors.FORCE_31));
                }

                if (conditionExpressions != null && checkConditionExpressions(conditionExpressions, ID)) {
                    issues.add(getContext().createConfigIssue(Groups.QUERY.name(),
                            ForceConfigBean.CONF_PREFIX + "soqlQuery", Errors.FORCE_32));
                }

                if (conf.repeatQuery == ForceRepeatQuery.INCREMENTAL) {
                    issues.add(getContext().createConfigIssue(Groups.QUERY.name(),
                            ForceConfigBean.CONF_PREFIX + "repeatQuery", Errors.FORCE_33));
                }
            } else {
                if (conditionExpressions == null
                        || !checkConditionExpressions(conditionExpressions, conf.offsetColumn)
                        || fieldOrderByList == null
                        || !checkFieldOrderByList(fieldOrderByList, conf.offsetColumn)) {
                    issues.add(getContext().createConfigIssue(Groups.QUERY.name(),
                            ForceConfigBean.CONF_PREFIX + "soqlQuery", Errors.FORCE_07, conf.offsetColumn));
                }
            }
        }
    }

    if (!conf.disableValidation && StringUtils.isEmpty(conf.initialOffset)) {
        issues.add(getContext().createConfigIssue(Groups.FORCE.name(),
                ForceConfigBean.CONF_PREFIX + "initialOffset", Errors.FORCE_00,
                "You must configure an Initial Offset"));
    }

    if (!conf.disableValidation && StringUtils.isEmpty(conf.offsetColumn)) {
        issues.add(getContext().createConfigIssue(Groups.FORCE.name(),
                ForceConfigBean.CONF_PREFIX + "queryExistingData", Errors.FORCE_00,
                "You must configure an Offset Column"));
    }

    if (issues.isEmpty()) {
        try {
            ConnectorConfig partnerConfig = ForceUtils.getPartnerConfig(conf, new ForceSessionRenewer());

            partnerConnection = new PartnerConnection(partnerConfig);
            if (conf.mutualAuth.useMutualAuth) {
                ForceUtils.setupMutualAuth(partnerConfig, conf.mutualAuth);
            }

            bulkConnection = ForceUtils.getBulkConnection(partnerConfig, conf);

            LOG.info("Successfully authenticated as {}", conf.username);

            if (conf.queryExistingData) {
                sobjectType = ForceUtils.getSobjectTypeFromQuery(conf.soqlQuery);
                LOG.info("Found sobject type {}", sobjectType);
                if (sobjectType == null) {
                    issues.add(getContext().createConfigIssue(Groups.QUERY.name(),
                            ForceConfigBean.CONF_PREFIX + "soqlQuery", Errors.FORCE_00,
                            "Badly formed SOQL Query: " + conf.soqlQuery));
                }
            }
        } catch (ConnectionException | AsyncApiException | StageException | URISyntaxException e) {
            LOG.error("Error connecting: {}", e);
            issues.add(getContext().createConfigIssue(Groups.FORCE.name(),
                    ForceConfigBean.CONF_PREFIX + "authEndpoint", Errors.FORCE_00,
                    ForceUtils.getExceptionCode(e) + ", " + ForceUtils.getExceptionMessage(e)));
        }
    }

    if (issues.isEmpty() && conf.subscribeToStreaming) {
        switch (conf.subscriptionType) {
        case PUSH_TOPIC:
            setObjectTypeFromQuery(issues);
            break;
        case PLATFORM_EVENT:
            // Do nothing
            break;
        case CDC:
            sobjectType = conf.cdcObject;
            break;
        }

        messageQueue = new ArrayBlockingQueue<>(2 * conf.basicConfig.maxBatchSize);
    }

    if (issues.isEmpty()) {
        recordCreator = buildRecordCreator();
        try {
            recordCreator.init();
        } catch (StageException e) {
            issues.add(getContext().createConfigIssue(null, null, Errors.FORCE_34, e));
        }
    }

    // If issues is not empty, the UI will inform the user of each configuration issue in the list.
    return issues;
}

From source file:org.bimserver.geometry.StreamingGeometryGenerator.java

@SuppressWarnings("unchecked")
public GenerateGeometryResult generateGeometry(long uoid, final DatabaseSession databaseSession,
        QueryContext queryContext, long nrObjects)
        throws BimserverDatabaseException, GeometryGeneratingException {
    GenerateGeometryResult generateGeometryResult = new GenerateGeometryResult();
    packageMetaData = queryContext.getPackageMetaData();
    productClass = packageMetaData.getEClass("IfcProduct");
    geometryFeature = productClass.getEStructuralFeature("geometry");
    representationFeature = productClass.getEStructuralFeature("Representation");
    representationsFeature = packageMetaData.getEClass("IfcProductDefinitionShape")
            .getEStructuralFeature("Representations");
    itemsFeature = packageMetaData.getEClass("IfcShapeRepresentation").getEStructuralFeature("Items");
    mappingSourceFeature = packageMetaData.getEClass("IfcMappedItem").getEStructuralFeature("MappingSource");

    GregorianCalendar now = new GregorianCalendar();
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
    debugIdentifier = dateFormat.format(now.getTime()) + " (" + report.getOriginalIfcFileName() + ")";

    long start = System.nanoTime();
    String pluginName = "";
    if (queryContext.getPackageMetaData().getSchema() == Schema.IFC4) {
        pluginName = "org.bimserver.ifc.step.serializer.Ifc4StepStreamingSerializerPlugin";
    } else if (queryContext.getPackageMetaData().getSchema() == Schema.IFC2X3TC1) {
        pluginName = "org.bimserver.ifc.step.serializer.Ifc2x3tc1StepStreamingSerializerPlugin";
    } else {//from w w w.j  a va2  s .c om
        throw new GeometryGeneratingException(
                "Unknown schema " + queryContext.getPackageMetaData().getSchema());
    }

    reuseGeometry = bimServer.getServerSettingsCache().getServerSettings().isReuseGeometry();
    optimizeMappedItems = bimServer.getServerSettingsCache().getServerSettings().isOptimizeMappedItems();

    report.setStart(new GregorianCalendar());
    report.setIfcSchema(queryContext.getPackageMetaData().getSchema());
    report.setUseMappingOptimization(optimizeMappedItems);
    report.setReuseGeometry(reuseGeometry);

    try {
        final StreamingSerializerPlugin ifcSerializerPlugin = (StreamingSerializerPlugin) bimServer
                .getPluginManager().getPlugin(pluginName, true);
        if (ifcSerializerPlugin == null) {
            throw new UserException("No IFC serializer found");
        }

        User user = (User) databaseSession.get(uoid, org.bimserver.database.OldQuery.getDefault());
        UserSettings userSettings = user.getUserSettings();

        report.setUserName(user.getName());
        report.setUserUserName(user.getUsername());

        RenderEnginePluginConfiguration renderEngine = null;
        if (eoid != -1) {
            renderEngine = databaseSession.get(eoid, OldQuery.getDefault());
        } else {
            renderEngine = userSettings.getDefaultRenderEngine();
        }
        if (renderEngine == null) {
            throw new UserException("No default render engine has been selected for this user");
        }
        renderEngineName = renderEngine.getName();

        int availableProcessors = Runtime.getRuntime().availableProcessors();
        report.setAvailableProcessors(availableProcessors);

        int maxSimultanousThreads = Math.min(
                bimServer.getServerSettingsCache().getServerSettings().getRenderEngineProcesses(),
                availableProcessors);
        if (maxSimultanousThreads < 1) {
            maxSimultanousThreads = 1;
        }

        final RenderEngineSettings settings = new RenderEngineSettings();
        settings.setPrecision(Precision.SINGLE);
        settings.setIndexFormat(IndexFormat.AUTO_DETECT);
        settings.setGenerateNormals(true);
        settings.setGenerateTriangles(true);
        settings.setGenerateWireFrame(false);

        final RenderEngineFilter renderEngineFilter = new RenderEngineFilter();

        RenderEnginePool renderEnginePool = bimServer.getRenderEnginePools().getRenderEnginePool(
                packageMetaData.getSchema(), renderEngine.getPluginDescriptor().getPluginClassName(),
                bimServer.getPluginSettingsCache().getPluginSettings(renderEngine.getOid()));

        report.setRenderEngineName(renderEngine.getName());
        report.setRenderEnginePluginVersion(
                renderEngine.getPluginDescriptor().getPluginBundleVersion().getVersion());

        try (RenderEngine engine = renderEnginePool.borrowObject()) {
            VersionInfo versionInfo = renderEnginePool.getRenderEngineFactory().getVersionInfo();
            report.setRenderEngineVersion(versionInfo);
            applyLayerSets = engine.isApplyLayerSets();
            report.setApplyLayersets(applyLayerSets);
            calculateQuantities = engine.isCalculateQuantities();
            report.setCalculateQuantities(calculateQuantities);
        }

        // TODO reuse, pool the pools :) Or something smarter
        // TODO reuse queue, or try to determine a realistic size, or don't use a fixed-size queue
        ThreadPoolExecutor executor = new ThreadPoolExecutor(maxSimultanousThreads, maxSimultanousThreads, 24,
                TimeUnit.HOURS, new ArrayBlockingQueue<Runnable>(10000000));

        JsonQueryObjectModelConverter jsonQueryObjectModelConverter = new JsonQueryObjectModelConverter(
                packageMetaData);
        String queryNameSpace = packageMetaData.getSchema().name().toLowerCase() + "-stdlib";

        // Al references should already be direct, since this is now done in BimServer on startup, quite the hack...
        Include objectPlacement = jsonQueryObjectModelConverter
                .getDefineFromFile(queryNameSpace + ":ObjectPlacement", true);

        Set<EClass> classes = null;
        if (queryContext.getOidCounters() != null) {
            classes = queryContext.getOidCounters().keySet();
        } else {
            classes = packageMetaData.getEClasses();
        }

        float multiplierToMm = processUnits(databaseSession, queryContext);
        generateGeometryResult.setMultiplierToMm(multiplierToMm);

        // Phase 1 (mapped item detection) sometimes detects that mapped items have invalid (unsupported) RepresentationIdentifier values, this set keeps track of objects to skip in Phase 2 because of that
        Set<Long> toSkip = new HashSet<>();

        for (EClass eClass : classes) {
            if (packageMetaData.getEClass("IfcProduct").isSuperTypeOf(eClass)) {
                int nrObjectsForType = 0;

                Query query2 = new Query(eClass.getName() + "Main query", packageMetaData);
                QueryPart queryPart2 = query2.createQueryPart();
                queryPart2.addType(eClass, false);
                Include representationInclude = queryPart2.createInclude();
                representationInclude.addType(eClass, false);
                representationInclude.addFieldDirect("Representation");
                Include representationsInclude = representationInclude.createInclude();
                representationsInclude.addType(packageMetaData.getEClass("IfcProductRepresentation"), true);
                representationsInclude.addFieldDirect("Representations");
                Include itemsInclude = representationsInclude.createInclude();
                itemsInclude.addType(packageMetaData.getEClass("IfcShapeRepresentation"), false);
                itemsInclude.addFieldDirect("Items");
                itemsInclude.addFieldDirect("ContextOfItems");
                Include mappingSourceInclude = itemsInclude.createInclude();
                mappingSourceInclude.addType(packageMetaData.getEClass("IfcMappedItem"), false);
                mappingSourceInclude.addFieldDirect("MappingSource");
                mappingSourceInclude.addFieldDirect("MappingTarget");
                Include representationMap = mappingSourceInclude.createInclude();
                representationMap.addType(packageMetaData.getEClass("IfcRepresentationMap"), false);
                representationMap.addFieldDirect("MappedRepresentation");
                Include createInclude = representationMap.createInclude();
                createInclude.addType(packageMetaData.getEClass("IfcShapeRepresentation"), true);

                Include targetInclude = mappingSourceInclude.createInclude();
                targetInclude.addType(packageMetaData.getEClass("IfcCartesianTransformationOperator3D"), false);
                targetInclude.addFieldDirect("Axis1");
                targetInclude.addFieldDirect("Axis2");
                targetInclude.addFieldDirect("Axis3");
                targetInclude.addFieldDirect("LocalOrigin");

                queryPart2.addInclude(objectPlacement);

                Map<Long, Map<Long, ProductDef>> representationMapToProduct = new HashMap<>();

                QueryObjectProvider queryObjectProvider2 = new QueryObjectProvider(databaseSession, bimServer,
                        query2, Collections.singleton(queryContext.getRoid()), packageMetaData);
                HashMapVirtualObject next = queryObjectProvider2.next();
                int nrProductsWithRepresentation = 0;
                while (next != null) {
                    if (next.eClass() == eClass) {
                        AbstractHashMapVirtualObject representation = next
                                .getDirectFeature(representationFeature);
                        if (representation != null) {
                            Set<HashMapVirtualObject> representations = representation
                                    .getDirectListFeature(representationsFeature);
                            if (representations != null) {
                                boolean foundValidContext = false;
                                for (HashMapVirtualObject representationItem : representations) {
                                    if (usableContext(representationItem)) {
                                        foundValidContext = true;
                                    }
                                }
                                if (foundValidContext) {
                                    nrProductsWithRepresentation++;
                                }
                                for (HashMapVirtualObject representationItem : representations) {
                                    if (!usableContext(representationItem) && foundValidContext) {
                                        continue;
                                    }
                                    if (hasValidRepresentationIdentifier(representationItem)) {
                                        Set<HashMapVirtualObject> items = representationItem
                                                .getDirectListFeature(itemsFeature);
                                        if (items == null || items.size() > 1) {
                                            // Only if there is just one item, we'll store this for reuse
                                            continue;
                                        }
                                        // So this next loop always results in 1 (or no) loops
                                        for (HashMapVirtualObject item : items) {
                                            report.addRepresentationItem(item.eClass().getName());
                                            if (!packageMetaData.getEClass("IfcMappedItem")
                                                    .isSuperTypeOf(item.eClass())) {
                                                nrObjectsForType++;
                                                continue; // All non IfcMappedItem objects will be done in phase 2
                                            }
                                            AbstractHashMapVirtualObject mappingTarget = item
                                                    .getDirectFeature(packageMetaData
                                                            .getEReference("IfcMappedItem", "MappingTarget"));
                                            AbstractHashMapVirtualObject mappingSourceOfMappedItem = item
                                                    .getDirectFeature(packageMetaData
                                                            .getEReference("IfcMappedItem", "MappingSource"));
                                            if (mappingSourceOfMappedItem == null) {
                                                LOGGER.info("No mapping source");
                                                continue;
                                            }
                                            AbstractHashMapVirtualObject mappedRepresentation = mappingSourceOfMappedItem
                                                    .getDirectFeature(packageMetaData.getEReference(
                                                            "IfcRepresentationMap", "MappedRepresentation"));

                                            if (!hasValidRepresentationIdentifier(mappedRepresentation)) {
                                                // Skip this mapping, we should store somewhere that this object should also be skipped in the normal way
                                                // TODO too many log statements, should log only 1 line for the complete model
                                                //                                       LOGGER.info("Skipping because of invalid RepresentationIdentifier in mapped item (" + (String) mappedRepresentation.get("RepresentationIdentifier") + ")");
                                                report.addSkippedBecauseOfInvalidRepresentationIdentifier(
                                                        (String) mappedRepresentation
                                                                .get("RepresentationIdentifier"));
                                                toSkip.add(next.getOid());
                                                continue;
                                            }
                                            double[] mappingMatrix = Matrix.identity();
                                            double[] productMatrix = Matrix.identity();
                                            if (mappingTarget != null) {
                                                AbstractHashMapVirtualObject axis1 = mappingTarget
                                                        .getDirectFeature(packageMetaData.getEReference(
                                                                "IfcCartesianTransformationOperator", "Axis1"));
                                                AbstractHashMapVirtualObject axis2 = mappingTarget
                                                        .getDirectFeature(packageMetaData.getEReference(
                                                                "IfcCartesianTransformationOperator", "Axis2"));
                                                AbstractHashMapVirtualObject axis3 = mappingTarget
                                                        .getDirectFeature(packageMetaData.getEReference(
                                                                "IfcCartesianTransformationOperator", "Axis3"));
                                                AbstractHashMapVirtualObject localOrigin = mappingTarget
                                                        .getDirectFeature(packageMetaData.getEReference(
                                                                "IfcCartesianTransformationOperator",
                                                                "LocalOrigin"));

                                                double[] a1 = null;
                                                double[] a2 = null;
                                                double[] a3 = null;

                                                if (axis3 != null) {
                                                    List<Double> list = (List<Double>) axis3
                                                            .get("DirectionRatios");
                                                    a3 = new double[] { list.get(0), list.get(1), list.get(2) };
                                                } else {
                                                    a3 = new double[] { 0, 0, 1, 1 };
                                                    Vector.normalize(a3);
                                                }

                                                if (axis1 != null) {
                                                    List<Double> list = (List<Double>) axis1
                                                            .get("DirectionRatios");
                                                    a1 = new double[] { list.get(0), list.get(1), list.get(2) };
                                                    Vector.normalize(a1);
                                                } else {
                                                    //                                          if (a3[0] == 1 && a3[1] == 0 && a3[2] == 0) {
                                                    a1 = new double[] { 1, 0, 0, 1 };
                                                    //                                          } else {
                                                    //                                             a1 = new double[]{0, 1, 0, 1};
                                                    //                                          }
                                                }

                                                double[] xVec = Vector.scalarProduct(Vector.dot(a1, a3), a3);
                                                double[] xAxis = Vector.subtract(a1, xVec);
                                                Vector.normalize(xAxis);

                                                if (axis2 != null) {
                                                    List<Double> list = (List<Double>) axis2
                                                            .get("DirectionRatios");
                                                    a2 = new double[] { list.get(0), list.get(1), list.get(2) };
                                                    Vector.normalize(a2);
                                                } else {
                                                    a2 = new double[] { 0, 1, 0, 1 };
                                                }

                                                double[] tmp = Vector.scalarProduct(Vector.dot(a2, a3), a3);
                                                double[] yAxis = Vector.subtract(a2, tmp);
                                                tmp = Vector.scalarProduct(Vector.dot(a2, xAxis), xAxis);
                                                yAxis = Vector.subtract(yAxis, tmp);
                                                Vector.normalize(yAxis);

                                                a2 = yAxis;
                                                a1 = xAxis;

                                                List<Double> t = (List<Double>) localOrigin.get("Coordinates");
                                                mappingMatrix = new double[] { a1[0], a1[1], a1[2], 0, a2[0],
                                                        a2[1], a2[2], 0, a3[0], a3[1], a3[2], 0,
                                                        t.get(0).doubleValue(), t.get(1).doubleValue(),
                                                        t.get(2).doubleValue(), 1 };
                                            }

                                            AbstractHashMapVirtualObject placement = next
                                                    .getDirectFeature(packageMetaData
                                                            .getEReference("IfcProduct", "ObjectPlacement"));
                                            if (placement != null) {
                                                productMatrix = placementToMatrix(placement);
                                            }

                                            AbstractHashMapVirtualObject mappingSource = item
                                                    .getDirectFeature(mappingSourceFeature);
                                            if (mappingSource != null) {
                                                Map<Long, ProductDef> map = representationMapToProduct
                                                        .get(((HashMapVirtualObject) mappingSource).getOid());
                                                if (map == null) {
                                                    map = new LinkedHashMap<>();
                                                    representationMapToProduct.put(
                                                            ((HashMapVirtualObject) mappingSource).getOid(),
                                                            map);
                                                }
                                                ProductDef pd = new ProductDef(next.getOid());
                                                pd.setMappedItemOid(item.getOid());
                                                pd.setObject(next);

                                                pd.setProductMatrix(productMatrix);
                                                pd.setMappingMatrix(mappingMatrix);
                                                map.put(next.getOid(), pd);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    next = queryObjectProvider2.next();
                }

                Set<Long> done = new HashSet<>();

                for (Long repMapId : representationMapToProduct.keySet()) {
                    Map<Long, ProductDef> map = representationMapToProduct.get(repMapId);

                    // When there is more than one instance using this mapping
                    if (map.size() > 1) {
                        Query query = new Query("Reuse query " + eClass.getName(), packageMetaData);
                        QueryPart queryPart = query.createQueryPart();
                        //                     QueryPart queryPart3 = query.createQueryPart();
                        queryPart.addType(eClass, false);
                        //                     queryPart3.addType(packageMetaData.getEClass("IfcMappedItem"), false);

                        long masterOid = map.values().iterator().next().getOid();

                        double[] inverted = Matrix.identity();
                        ProductDef masterProductDef = map.get(masterOid);
                        if (!Matrix.invertM(inverted, 0, masterProductDef.getMappingMatrix(), 0)) {
                            LOGGER.debug("No inverse, this mapping will be skipped and processed as normal");
                            // This is probably because of mirroring of something funky

                            // TODO we should however be able to squeeze out a little more reuse by finding another master...
                            continue;
                        }

                        for (ProductDef pd : map.values()) {
                            done.add(pd.getOid());
                            if (!optimizeMappedItems) {
                                queryPart.addOid(pd.getOid());

                                // In theory these should be fused together during querying
                                //                           queryPart3.addOid(pd.getMappedItemOid());
                            } else {
                                pd.setMasterOid(masterOid);
                            }
                        }
                        if (optimizeMappedItems) {
                            queryPart.addOid(masterOid);
                        }

                        LOGGER.debug("Running " + map.size()
                                + " objects in one batch because of reused geometry " + (eClass.getName()));

                        //                     queryPart3.addInclude(jsonQueryObjectModelConverter.getDefineFromFile("ifc2x3tc1-stdlib:IfcMappedItem"));

                        processQuery(databaseSession, queryContext, generateGeometryResult, ifcSerializerPlugin,
                                settings, renderEngineFilter, renderEnginePool, executor, eClass, query,
                                queryPart, true, map, map.size());
                    }
                }

                Query query3 = new Query("Remaining " + eClass.getName(), packageMetaData);
                QueryPart queryPart3 = query3.createQueryPart();
                queryPart3.addType(eClass, false);
                Include include3 = queryPart3.createInclude();
                include3.addType(eClass, false);
                include3.addFieldDirect("Representation");
                Include rInclude = include3.createInclude();
                rInclude.addType(packageMetaData.getEClass("IfcProductRepresentation"), true);
                rInclude.addFieldDirect("Representations");
                Include representationsInclude2 = rInclude.createInclude();
                representationsInclude2.addType(packageMetaData.getEClass("IfcShapeModel"), true);
                representationsInclude2.addFieldDirect("ContextOfItems");

                queryObjectProvider2 = new QueryObjectProvider(databaseSession, bimServer, query3,
                        Collections.singleton(queryContext.getRoid()), packageMetaData);
                next = queryObjectProvider2.next();

                Query query = new Query("Main " + eClass.getName(), packageMetaData);
                QueryPart queryPart = query.createQueryPart();
                int written = 0;

                int maxObjectsPerFile = 0;
                if (nrProductsWithRepresentation <= 100) {
                    maxObjectsPerFile = 1;
                } else if (nrProductsWithRepresentation < 10000) {
                    maxObjectsPerFile = (int) (nrProductsWithRepresentation / 100);
                } else {
                    maxObjectsPerFile = 100;
                }

                //               LOGGER.info(report.getOriginalIfcFileName());
                //               LOGGER.info("Max objects per file: " + maxObjectsPerFile + " (" + eClass.getName() + ": " + nrProductsWithRepresentation + ")");

                report.setMaxPerFile(maxObjectsPerFile);

                while (next != null) {
                    if (next.eClass() == eClass && !done.contains(next.getOid())
                            && !toSkip.contains(next.getOid())) {
                        AbstractHashMapVirtualObject representation = next
                                .getDirectFeature(representationFeature);
                        if (representation != null) {
                            Set<HashMapVirtualObject> list = representation.getDirectListFeature(packageMetaData
                                    .getEReference("IfcProductRepresentation", "Representations"));
                            boolean goForIt = goForIt(list);
                            if (goForIt) {
                                if (next.eClass() == eClass && !done.contains(next.getOid())) {
                                    representation = next.getDirectFeature(representationFeature);
                                    if (representation != null) {
                                        list = representation.getDirectListFeature(packageMetaData
                                                .getEReference("IfcProductRepresentation", "Representations"));
                                        boolean goForIt2 = goForIt(list);
                                        if (goForIt2) {
                                            queryPart.addOid(next.getOid());
                                            written++;
                                            if (written >= maxObjectsPerFile) {
                                                processQuery(databaseSession, queryContext,
                                                        generateGeometryResult, ifcSerializerPlugin, settings,
                                                        renderEngineFilter, renderEnginePool, executor, eClass,
                                                        query, queryPart, false, null, written);
                                                query = new Query("Main " + eClass.getName(), packageMetaData);
                                                queryPart = query.createQueryPart();
                                                written = 0;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    next = queryObjectProvider2.next();
                }
                if (written > 0) {
                    processQuery(databaseSession, queryContext, generateGeometryResult, ifcSerializerPlugin,
                            settings, renderEngineFilter, renderEnginePool, executor, eClass, query, queryPart,
                            false, null, written);
                }
            }
        }

        allJobsPushed = true;

        executor.shutdown();
        executor.awaitTermination(24, TimeUnit.HOURS);

        // Need total bounds
        //         float[] quantizationMatrix = createQuantizationMatrixFromBounds(boundsMm);
        //         ByteBuffer verticesQuantized = quantizeVertices(vertices, quantizationMatrix, generateGeometryResult.getMultiplierToMm());
        //         geometryData.setAttribute(GeometryPackage.eINSTANCE.getGeometryData_VerticesQuantized(), verticesQuantized.array());

        LOGGER.debug("Generating quantized vertices");
        double[] quantizationMatrix = createQuantizationMatrixFromBounds(
                generateGeometryResult.getBoundsUntransformed(), multiplierToMm);
        for (Long id : geometryDataMap.keySet()) {
            Tuple<HashMapVirtualObject, ByteBuffer> tuple = geometryDataMap.get(id);

            HashMapVirtualObject buffer = new HashMapVirtualObject(queryContext,
                    GeometryPackage.eINSTANCE.getBuffer());
            //            Buffer buffer = databaseSession.create(Buffer.class);
            buffer.set("data",
                    quantizeVertices(tuple.getB().asDoubleBuffer(), quantizationMatrix, multiplierToMm)
                            .array());
            //            buffer.setData(quantizeVertices(tuple.getB(), quantizationMatrix, multiplierToMm).array());
            //            databaseSession.store(buffer);
            buffer.save();
            HashMapVirtualObject geometryData = tuple.getA();
            geometryData.set("verticesQuantized", buffer.getOid());
            int reused = (int) geometryData.eGet(GeometryPackage.eINSTANCE.getGeometryData_Reused());
            int nrTriangles = (int) geometryData.eGet(GeometryPackage.eINSTANCE.getGeometryData_NrIndices())
                    / 3;
            int saveableTriangles = Math.max(0, (reused - 1)) * nrTriangles;
            geometryData.set("saveableTriangles", saveableTriangles);
            //            if (saveableTriangles > 0) {
            //               System.out.println("Saveable triangles: " + saveableTriangles);
            //            }
            geometryData.saveOverwrite();
        }

        long end = System.nanoTime();
        long total = totalBytes.get()
                - (bytesSavedByHash.get() + bytesSavedByTransformation.get() + bytesSavedByMapping.get());
        LOGGER.info("Rendertime: " + Formatters.nanosToString(end - start) + ", " + "Reused (by hash): "
                + Formatters.bytesToString(bytesSavedByHash.get()) + ", Reused (by transformation): "
                + Formatters.bytesToString(bytesSavedByTransformation.get()) + ", Reused (by mapping): "
                + Formatters.bytesToString(bytesSavedByMapping.get()) + ", Total: "
                + Formatters.bytesToString(totalBytes.get()) + ", Final: " + Formatters.bytesToString(total));
        if (report.getNumberOfDebugFiles() > 0) {
            LOGGER.error("Number of erroneous files: " + report.getNumberOfDebugFiles());
        }
        Map<String, Integer> skipped = report.getSkippedBecauseOfInvalidRepresentationIdentifier();
        if (skipped.size() > 0) {
            LOGGER.error("Number of representations skipped:");
            for (String identifier : skipped.keySet()) {
                LOGGER.error("\t" + identifier + ": " + skipped.get(identifier));
            }
        }
        String dump = geometryGenerationDebugger.dump();
        if (dump != null) {
            LOGGER.info(dump);
        }
    } catch (Exception e) {
        running = false;
        LOGGER.error("", e);
        report.setEnd(new GregorianCalendar());
        throw new GeometryGeneratingException(e);
    }
    report.setEnd(new GregorianCalendar());
    try {
        if (report.getNumberOfDebugFiles() > 0) {
            writeDebugFile();
        }
    } catch (IOException e) {
        LOGGER.debug("", e);
    }
    return generateGeometryResult;
}