All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.notifications.center.NotificationCenterManager Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.netbeans.modules.notifications.center;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import org.netbeans.modules.notifications.NotificationImpl;
import org.netbeans.modules.notifications.filter.FilterRepository;
import org.netbeans.modules.notifications.filter.TitleFilter;
import org.netbeans.modules.notifications.filter.NotificationFilter;
import org.openide.awt.NotificationDisplayer.Category;

/**
 *
 * @author jpeska
 */
public class NotificationCenterManager {

    public static final String PROP_NOTIFICATIONS_CHANGED = "notificationsChanged"; //NOI18N
    public static final String PROP_NOTIFICATION_ADDED = "notificationAdded"; //NOI18N
    public static final String PROP_NOTIFICATION_READ = "notificationRead"; //NOI18N
    private static final int NOTIFICATIONS_CAPACITY = 100;
    private static final PropertyChangeSupport propSupport = new PropertyChangeSupport(NotificationCenterManager.class);
    private static NotificationCenterManager instance = null;
    private final List notifications = new ArrayList();
    private final List filteredNotifications = new ArrayList();
    private NotificationTable notificationTable;
    private final FilterRepository filterRepository;
    private NotificationFilter notificationFilter;
    private TitleFilter titleFilter;

    private NotificationCenterManager() {
        filterRepository = FilterRepository.getInstance();
        loadFilters();
    }

    public static NotificationCenterManager getInstance() {
        if (instance == null) {
            instance = new NotificationCenterManager();
        }
        return instance;
    }

    public void add(NotificationImpl notification) {
        boolean capacityFull = false;
        synchronized (notifications) {
            capacityFull = notifications.size() == NOTIFICATIONS_CAPACITY;
            if (capacityFull) {
                notifications.remove(0).clear();
            }
            notifications.add(notification);
        }
        if (isEnabled(notification)) {
            filteredNotifications.add(notification);
            firePropertyChange(PROP_NOTIFICATION_ADDED, notification);
        }
        updateTable(capacityFull);
    }

    public void delete(NotificationImpl notification) {
        synchronized (notifications) {
            if (!notifications.remove(notification)) {
                return;
            }
        }
        if (isEnabled(notification)) {
            filteredNotifications.remove(notification);
            if (!notification.isRead()) {
                firePropertyChange(PROP_NOTIFICATION_READ, notification);
            }
        }
        updateTable(false);
    }

    public void updateTable(boolean filter) {
        if (filter) {
            filterNotifications();
        }
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                NotificationTableModel model = getModel();
                synchronized (notifications) {
                    model.setEntries(filteredNotifications);
                }
            }
        });
    }

    public void update(NotificationImpl n) {
        final int index;
        synchronized (notifications) {
            index = filteredNotifications.indexOf(n);
        }
        if (index != -1) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    NotificationTableModel model = getModel();
                    model.updateIndex(index);
                }
            });
        }
    }

    public void deleteAll() {
        synchronized (notifications) {
            notifications.clear();
            filteredNotifications.clear();
            firePropertyChange(PROP_NOTIFICATIONS_CHANGED, null);
            updateTable(false);
        }
    }

    public void markAllRead() {
        synchronized (notifications) {
            for (NotificationImpl n : notifications) {
                n.markAsRead(true);
            }
        }
    }

    public List getCategories() {
        return Category.getCategories();
    }

    public void wasRead(NotificationImpl notification) {
        firePropertyChange(PROP_NOTIFICATION_READ, notification);
        update(notification);
    }

    public NotificationFilter getActiveFilter() {
        return notificationFilter;
    }

    public JComponent getComponent() {
        return getTable();
    }

    private NotificationTableModel getModel() {
        return (NotificationTableModel) getTable().getModel();
    }

    public int getUnreadCount() {
        int count = 0;
        synchronized (notifications) {
            for (NotificationImpl notification : notifications) {
                if (!notification.isRead()) {
                    count++;
                }
            }
        }
        return count;
    }

    public NotificationImpl getLastUnreadNotification() {
        synchronized (notifications) {
            for (int i = filteredNotifications.size() - 1; i >= 0; i--) {
                NotificationImpl n = filteredNotifications.get(i);
                if (!n.isRead()) {
                    return n;
                }
            }
        }
        return null;
    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        propSupport.addPropertyChangeListener(l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        propSupport.removePropertyChangeListener(l);
    }

    private void firePropertyChange(final String propName, final NotificationImpl notification) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                if (PROP_NOTIFICATION_ADDED.equals(propName)) {
                    notification.initDecorations();
                }
                propSupport.firePropertyChange(propName, null, notification);
            }
        };
        if (SwingUtilities.isEventDispatchThread()) {
            r.run();
        } else {
            SwingUtilities.invokeLater(r);
        }
    }

    static void tcClosed() {
        try {
            FilterRepository.getInstance().save();
        } catch (IOException ioE) {
            getLogger().log(Level.INFO, null, ioE);
        }
    }

    static Logger getLogger() {
        return Logger.getLogger(NotificationCenterManager.class.getName());
    }

    public boolean isEnabled(NotificationImpl notification) {
        boolean categoryEnabled = notificationFilter == null || (notificationFilter != null && notificationFilter.isEnabled(notification));
        boolean titleEnabled = true;
        if (categoryEnabled) {//save unnecessary condition check
            titleEnabled = titleFilter == null ? true : titleFilter.isEnabled(notification.getTitle());
        }
        return categoryEnabled && titleEnabled;
    }

    private void filterNotifications() {
        notificationFilter = filterRepository.getActive();
        synchronized (notifications) {
            filteredNotifications.clear();
            for (NotificationImpl notification : notifications) {
                if (isEnabled(notification)) {
                    filteredNotifications.add(notification);
                }
            }
        }
        firePropertyChange(PROP_NOTIFICATIONS_CHANGED, null);
    }

    void setMessageFilter(String searchText) {
        if (searchText == null || searchText.isEmpty()) {
            titleFilter = null;
        } else {
            titleFilter = new TitleFilter(searchText);
        }
        updateTable(true);
    }

    boolean isQuickFilter() {
        return titleFilter != null;
    }

    private void loadFilters() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    filterRepository.load();
                } catch (IOException ioE) {
                    getLogger().log(Level.INFO, ioE.getMessage(), ioE);
                }
                if (notificationTable != null) {
                    updateTable(true);
                } else {
                    notificationFilter = filterRepository.getActive();
                }
            }
        }).start();
    }

    private NotificationTable getTable() {
        if (notificationTable == null) {
            notificationTable = new NotificationTable();
        }
        return notificationTable;
    }

    /**
     * for testing
     */
    void setActiveFilter(NotificationFilter notificationFilter) {
        this.notificationFilter = notificationFilter;
        filterNotifications();
    }

    /**
     * for testing
     */
    int getTotalCount() {
        int count = 0;
        synchronized (notifications) {
            count = notifications.size();
        }
        return count;
    }

    /**
     * for testing
     */
    int getFilteredCount() {
        int count = 0;
        synchronized (notifications) {
            count = filteredNotifications.size();
        }
        return count;
    }

    /**
     * for testing
     */
    List getFilteredNotifications() {
        return filteredNotifications;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy