diff --git a/Core/src/org/sleuthkit/autopsy/actions/ViewOsAccountAction.java b/Core/src/org/sleuthkit/autopsy/actions/ViewOsAccountAction.java index 200759fbf5..1f5d046704 100644 --- a/Core/src/org/sleuthkit/autopsy/actions/ViewOsAccountAction.java +++ b/Core/src/org/sleuthkit/autopsy/actions/ViewOsAccountAction.java @@ -52,11 +52,12 @@ public class ViewOsAccountAction extends AbstractAction { @Override public void actionPerformed(ActionEvent e) { WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + final DirectoryTreeTopComponent topComp = DirectoryTreeTopComponent.findInstance(); new SwingWorker() { @Override protected Void doInBackground() throws Exception { - DirectoryTreeTopComponent.findInstance().viewOsAccount(osAccount); + topComp.viewOsAccount(osAccount); return null; } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java index 32e808ff22..6876ccb704 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataResultPanel.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.corecomponents; import com.google.common.eventbus.Subscribe; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.awt.Cursor; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -32,6 +33,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; @@ -75,7 +78,6 @@ import org.sleuthkit.autopsy.mainui.datamodel.CreditCardBinSearchParams; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardDAO.CreditCardByBinFetcher; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardDAO.CreditCardByFileFetcher; import org.sleuthkit.autopsy.mainui.datamodel.CreditCardFileSearchParams; -import org.sleuthkit.autopsy.mainui.datamodel.CreditCardSearchParams; import org.sleuthkit.autopsy.mainui.datamodel.events.DAOAggregateEvent; import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactDAO.DataArtifactFetcher; import org.sleuthkit.autopsy.mainui.datamodel.DataArtifactSearchParam; @@ -194,6 +196,9 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C }; private final PropertyChangeListener weakDAOListener = WeakListeners.propertyChange(DAOListener, mainDAO); + + private ExecutorService nodeBackgroundTasksPool; + private static final Integer MAX_POOL_SIZE = 10; /** * Creates and opens a Swing JPanel with a JTabbedPane child component that @@ -1551,11 +1556,19 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C SwingUtilities.invokeLater(() -> displaySearchResults(searchResults, resetPaging, childSelectionInfo)); return; } + + // Stop any running background threads. + if(nodeBackgroundTasksPool != null) { + nodeBackgroundTasksPool.shutdown(); + } + + nodeBackgroundTasksPool = Executors.newFixedThreadPool(MAX_POOL_SIZE, + new ThreadFactoryBuilder().setNameFormat("DataResultPanel-background-task-%d").build()); if (searchResults == null) { setNode(null, resetPaging); } else { - SearchResultRootNode node = new SearchResultRootNode(searchResults); + SearchResultRootNode node = new SearchResultRootNode(searchResults, nodeBackgroundTasksPool); node.setNodeSelectionInfo(childSelectionInfo); setNode(node, resetPaging); setNumberOfChildNodes( diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java index 23471dad6a..9761bb00e9 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ImageNode.java @@ -36,7 +36,7 @@ import org.sleuthkit.autopsy.casemodule.DeleteDataSourceAction; import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.directorytree.ExplorerNodeActionVisitor; -import org.sleuthkit.autopsy.directorytree.FileSearchAction; +import org.sleuthkit.autopsy.directorytree.FileSearchTreeAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; @@ -105,7 +105,7 @@ public class ImageNode extends AbstractContentNode { List actionsList = new ArrayList<>(); actionsList.addAll(ExplorerNodeActionVisitor.getActions(content)); - actionsList.add(new FileSearchAction(Bundle.ImageNode_getActions_openFileSearchByAttr_text(), content.getId())); + actionsList.add(new FileSearchTreeAction(Bundle.ImageNode_getActions_openFileSearchByAttr_text(), content.getId())); actionsList.add(new ViewSummaryInformationAction(content.getId())); actionsList.add(new RunIngestModulesAction(Collections.singletonList(content))); actionsList.add(new NewWindowViewAction(NbBundle.getMessage(this.getClass(), "ImageNode.getActions.viewInNewWin.text"), this)); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/SpecialDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/SpecialDirectoryNode.java index e0ed80a69f..287b64c9ad 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/SpecialDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/SpecialDirectoryNode.java @@ -29,7 +29,7 @@ import org.sleuthkit.autopsy.datasourcesummary.ui.ViewSummaryInformationAction; import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.directorytree.ExportCSVAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; -import org.sleuthkit.autopsy.directorytree.FileSearchAction; +import org.sleuthkit.autopsy.directorytree.FileSearchTreeAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction; import org.sleuthkit.datamodel.Content; @@ -62,7 +62,7 @@ public abstract class SpecialDirectoryNode extends AbstractAbstractFileNodesingletonList(content))); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index f46ae9e197..5e05da6f60 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -87,6 +87,7 @@ import org.sleuthkit.autopsy.datamodel.Tags; import org.sleuthkit.autopsy.datamodel.ViewsNode; import org.sleuthkit.autopsy.datamodel.accounts.Accounts; import org.sleuthkit.autopsy.corecomponents.SelectionResponder; +import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.datamodel.CreditCards; import org.sleuthkit.autopsy.datamodel.accounts.BINRange; import org.sleuthkit.autopsy.mainui.datamodel.EmailsDAO; @@ -461,6 +462,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat * * @return getDefault() - the default instance */ + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) public static synchronized DirectoryTreeTopComponent findInstance() { WindowManager winManager = WindowManager.getDefault(); TopComponent win = winManager.findTopComponent(PREFERRED_ID); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSearchProvider.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSearchProvider.java deleted file mode 100644 index 523a4a69bd..0000000000 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSearchProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2011-2021 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed 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.sleuthkit.autopsy.directorytree; - -/** - * Lookup interface for File Search (to deal with circular deps) - */ -public interface FileSearchProvider { - - public void showDialog(Long dataSourceID); - - @Deprecated - public void showDialog(); -} diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/FileSearchAction.java b/Core/src/org/sleuthkit/autopsy/directorytree/FileSearchTreeAction.java similarity index 80% rename from Core/src/org/sleuthkit/autopsy/directorytree/FileSearchAction.java rename to Core/src/org/sleuthkit/autopsy/directorytree/FileSearchTreeAction.java index 348d3d5148..76ab9e6f7f 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/FileSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/FileSearchTreeAction.java @@ -20,14 +20,15 @@ package org.sleuthkit.autopsy.directorytree; import java.awt.event.ActionEvent; import javax.swing.AbstractAction; -import org.openide.util.Lookup; +import org.sleuthkit.autopsy.filesearch.FileSearchAction; /** * The “File Search by Attributes” action for data sources in the tree. */ -public class FileSearchAction extends AbstractAction { +public class FileSearchTreeAction extends AbstractAction { private final long dataSourceId; + private FileSearchAction searcher; /** * Main constructor. @@ -36,14 +37,17 @@ public class FileSearchAction extends AbstractAction { * @param dataSourceID The data source id of the item that is selected in * the tree. */ - public FileSearchAction(String title, long dataSourceID) { + public FileSearchTreeAction(String title, long dataSourceID) { super(title); dataSourceId = dataSourceID; } @Override public void actionPerformed(ActionEvent e) { - FileSearchProvider searcher = Lookup.getDefault().lookup(FileSearchProvider.class); + if(searcher == null) { + searcher = FileSearchAction.getDefault(); + } + searcher.showDialog(dataSourceId); } diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties index 78fe3b05ee..a13db56a3f 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties @@ -61,3 +61,4 @@ DateSearchPanel.dateFormatLabel.text=*The date format is mm/dd/yyyy MimeTypePanel.noteLabel.text=*Note: Multiple MIME types can be selected HashSearchPanel.sha256CheckBox.text=SHA-256: HashSearchPanel.sha256TextField.text= +FileSearchPanel.closeButton.text=Close diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED index 075a0e7afb..604fe21cfe 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/filesearch/Bundle.properties-MERGED @@ -80,3 +80,4 @@ DateSearchPanel.dateFormatLabel.text=*The date format is mm/dd/yyyy MimeTypePanel.noteLabel.text=*Note: Multiple MIME types can be selected HashSearchPanel.sha256CheckBox.text=SHA-256: HashSearchPanel.sha256TextField.text= +FileSearchPanel.closeButton.text=Close diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DataSourceFilter.java b/Core/src/org/sleuthkit/autopsy/filesearch/DataSourceFilter.java index 1d0063a8ff..b9862a10d9 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DataSourceFilter.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DataSourceFilter.java @@ -19,7 +19,10 @@ package org.sleuthkit.autopsy.filesearch; import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.util.EnumSet; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.casemodule.Case; /** * Filter by mime type used in filter areas of file search by attribute. diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/DataSourcePanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/DataSourcePanel.java index 6fc610b224..aa45bd68ce 100755 --- a/Core/src/org/sleuthkit/autopsy/filesearch/DataSourcePanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/DataSourcePanel.java @@ -18,9 +18,11 @@ */ package org.sleuthkit.autopsy.filesearch; +import java.beans.PropertyChangeEvent; import java.io.File; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -53,6 +55,18 @@ public class DataSourcePanel extends javax.swing.JPanel { public DataSourcePanel() { initComponents(); resetDataSourcePanel(); + + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.DATA_SOURCE_ADDED), (PropertyChangeEvent evt) -> { + if(evt.getPropertyName().equals(Case.Events.DATA_SOURCE_ADDED.toString())) { + List strings = getDataSourceArray(); + for (String dataSource : strings) { + DefaultListModel model = (DefaultListModel) dataSourceList.getModel(); + if(!model.contains(dataSource)) { + model.addElement(dataSource); + } + } + } + }); } /** diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchAction.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchAction.java index 11d8f94561..1e271492c8 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchAction.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchAction.java @@ -25,16 +25,16 @@ import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.actions.CallableSystemAction; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.directorytree.FileSearchProvider; +import org.sleuthkit.autopsy.timeline.OpenTimelineAction; -final class FileSearchAction extends CallableSystemAction implements FileSearchProvider { +final public class FileSearchAction extends CallableSystemAction { private static final long serialVersionUID = 1L; private static FileSearchAction instance = null; private static FileSearchDialog searchDialog; private static Long selectedDataSourceId; - FileSearchAction() { + private FileSearchAction() { super(); setEnabled(Case.isCaseOpen()); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { @@ -49,7 +49,7 @@ final class FileSearchAction extends CallableSystemAction implements FileSearchP public static FileSearchAction getDefault() { if (instance == null) { - instance = new FileSearchAction(); + instance = CallableSystemAction.get(FileSearchAction.class); } return instance; } @@ -89,15 +89,12 @@ final class FileSearchAction extends CallableSystemAction implements FileSearchP return false; } - @Override public void showDialog(Long dataSourceId) { selectedDataSourceId = dataSourceId; performAction(); } - @Override - @Deprecated public void showDialog() { showDialog(null); } diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchDialog.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchDialog.java index a98e531700..ff3336ce5f 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchDialog.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchDialog.java @@ -42,12 +42,18 @@ final class FileSearchDialog extends javax.swing.JDialog { setResizable(false); this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow()); fileSearchPanel1.addListenerToAll(new ActionListener() { - @Override public void actionPerformed(ActionEvent e) { setVisible(false); } }); + + fileSearchPanel1.addCloseListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); } /** diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form index f6fd00903f..a7d7ac4e6c 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.form @@ -18,32 +18,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -56,18 +31,45 @@ + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -77,6 +79,11 @@ + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java index 14b1578076..702b09b505 100644 --- a/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java +++ b/Core/src/org/sleuthkit/autopsy/filesearch/FileSearchPanel.java @@ -358,6 +358,10 @@ class FileSearchPanel extends javax.swing.JPanel { fsf.addActionListener(l); } } + + void addCloseListener(ActionListener l) { + closeButton.addActionListener(l); + } /** * This method is called from within the constructor to initialize the form. @@ -367,46 +371,57 @@ class FileSearchPanel extends javax.swing.JPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; filterPanel = new javax.swing.JPanel(); + buttonPanel = new javax.swing.JPanel(); searchButton = new javax.swing.JButton(); + closeButton = new javax.swing.JButton(); errorLabel = new javax.swing.JLabel(); setPreferredSize(new java.awt.Dimension(300, 300)); + setLayout(new java.awt.GridBagLayout()); filterPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); filterPanel.setPreferredSize(new java.awt.Dimension(300, 400)); filterPanel.setLayout(new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(filterPanel, gridBagConstraints); + + buttonPanel.setLayout(new java.awt.GridLayout(1, 0, 3, 0)); searchButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.searchButton.text")); // NOI18N + buttonPanel.add(searchButton); + + closeButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.closeButton.text")); // NOI18N + buttonPanel.add(closeButton); + + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5); + add(buttonPanel, gridBagConstraints); - errorLabel.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.errorLabel.text")); // NOI18N errorLabel.setForeground(new java.awt.Color(255, 51, 51)); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(searchButton) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(searchButton) - .addComponent(errorLabel)) - .addContainerGap()) - ); + errorLabel.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.errorLabel.text")); // NOI18N + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + add(errorLabel, gridBagConstraints); }// //GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPanel buttonPanel; + private javax.swing.JButton closeButton; private javax.swing.JLabel errorLabel; private javax.swing.JPanel filterPanel; private javax.swing.JButton searchButton; diff --git a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobExecutor.java b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobExecutor.java index 84da5c53a8..44b28c415a 100644 --- a/Core/src/org/sleuthkit/autopsy/ingest/IngestJobExecutor.java +++ b/Core/src/org/sleuthkit/autopsy/ingest/IngestJobExecutor.java @@ -365,12 +365,12 @@ final class IngestJobExecutor { * thread executing an ingest task, so such a job would run forever, * doing nothing, without a check here. */ - checkForTierCompleted(); + checkForTierCompleted(moduleTierIndex); } } /** - * Estimates the files to be prcessed in the current tier. + * Estimates the files to be processed in the current tier. */ private void estimateFilesToProcess() { estimatedFilesToProcess = 0; @@ -487,7 +487,7 @@ final class IngestJobExecutor { * job, so such a job would run forever, doing nothing, without * a check here. */ - checkForTierCompleted(); + checkForTierCompleted(moduleTierIndex); } } } @@ -497,11 +497,16 @@ final class IngestJobExecutor { * module tier are completed, and does an appropriate state transition if * they are. */ - private void checkForTierCompleted() { + private void checkForTierCompleted(int currentTier) { synchronized (tierTransitionLock) { if (jobState.equals(IngestJobState.ACCEPTING_STREAMED_CONTENT_AND_ANALYZING)) { return; } + if (currentTier < moduleTierIndex) { + // We likely had a leftover task from the previous tier. Since we've already + // advanced to the next tier, ignore it. + return; + } if (taskScheduler.currentTasksAreCompleted(getIngestJobId())) { do { shutDownCurrentTier(); @@ -512,7 +517,7 @@ final class IngestJobExecutor { shutDown(); break; } - } while (taskScheduler.currentTasksAreCompleted(getIngestJobId())); + } while (taskScheduler.currentTasksAreCompleted(getIngestJobId())); // Loop again immediately in case the new tier is empty } } } @@ -566,8 +571,11 @@ final class IngestJobExecutor { } } } finally { + // Save the module tier assocaited with this task since it could change after + // notifyTaskComplete + int currentTier = moduleTierIndex; taskScheduler.notifyTaskCompleted(task); - checkForTierCompleted(); + checkForTierCompleted(currentTier); } } @@ -619,8 +627,11 @@ final class IngestJobExecutor { logger.log(Level.SEVERE, String.format("File ingest thread interrupted during execution of file ingest job (file object ID = %d, thread ID = %d)", task.getFileId(), task.getThreadId()), ex); Thread.currentThread().interrupt(); } finally { + // Save the module tier assocaited with this task since it could change after + // notifyTaskComplete + int currentTier = moduleTierIndex; taskScheduler.notifyTaskCompleted(task); - checkForTierCompleted(); + checkForTierCompleted(currentTier); } } @@ -644,13 +655,16 @@ final class IngestJobExecutor { } } } finally { + // Save the module tier assocaited with this task since it could change after + // notifyTaskComplete + int currentTier = moduleTierIndex; taskScheduler.notifyTaskCompleted(task); - checkForTierCompleted(); + checkForTierCompleted(currentTier); } } /** - * Passes an analyisis result from the data source for the ingest job + * Passes an analysis result from the data source for the ingest job * through the analysis result ingest module pipeline. * * @param task An analysis result ingest task encapsulating the analysis @@ -669,8 +683,11 @@ final class IngestJobExecutor { } } } finally { + // Save the module tier assocaited with this task since it could change after + // notifyTaskComplete + int currentTier = moduleTierIndex; taskScheduler.notifyTaskCompleted(task); - checkForTierCompleted(); + checkForTierCompleted(currentTier); } } @@ -793,6 +810,12 @@ final class IngestJobExecutor { * Shuts down the ingest module pipelines in the current module tier. */ private void shutDownCurrentTier() { + // Note that this method is only called while holding the tierTransitionLock, so moduleTierIndex can not change + // during execution. + if (moduleTierIndex >= ingestModuleTiers.size()) { + logErrorMessage(Level.SEVERE, "shutDownCurrentTier called with out-of-bounds moduleTierIndex (" + moduleTierIndex + ")"); + return; + } logInfoMessage(String.format("Finished all ingest tasks for tier %s of ingest job", moduleTierIndex)); //NON-NLS jobState = IngestJobExecutor.IngestJobState.PIPELINES_SHUTTING_DOWN; IngestModuleTier moduleTier = ingestModuleTiers.get(moduleTierIndex); @@ -861,7 +884,7 @@ final class IngestJobExecutor { * @return The currently running module, may be null. */ DataSourceIngestPipeline.DataSourcePipelineModule getCurrentDataSourceIngestModule() { - Optional pipeline = ingestModuleTiers.get(moduleTierIndex).getDataSourceIngestPipeline(); + Optional pipeline = getCurrentDataSourceIngestPipelines(); if (pipeline.isPresent()) { return (DataSourceIngestPipeline.DataSourcePipelineModule) pipeline.get().getCurrentlyRunningModule(); } else { @@ -963,7 +986,7 @@ final class IngestJobExecutor { } pausedIngestThreads.clear(); } - checkForTierCompleted(); + checkForTierCompleted(moduleTierIndex); } /** @@ -1407,6 +1430,35 @@ final class IngestJobExecutor { logErrorMessage(Level.SEVERE, String.format("%s experienced an error during analysis while processing file %s (object ID = %d)", error.getModuleDisplayName(), file.getName(), file.getId()), error.getThrowable()); //NON-NLS } } + + /** + * Safely gets the file ingest pipelines for the current tier. + * + * @return The file ingest pipelines or empty if ingest has completed/is shutting down. + */ + Optional> getCurrentFileIngestPipelines() { + // Make a local copy in case the tier increments + int currentModuleTierIndex = moduleTierIndex; + if (currentModuleTierIndex < ingestModuleTiers.size()) { + return Optional.of(ingestModuleTiers.get(currentModuleTierIndex).getFileIngestPipelines()); + } + return Optional.empty(); + } + + /** + * Safely gets the data source ingest pipeline for the current tier. + * + * @return The data source ingest pipeline or empty if ingest has completed/is shutting down. + */ + Optional getCurrentDataSourceIngestPipelines() { + // Make a local copy in case the tier increments + int currentModuleTierIndex = moduleTierIndex; + if (currentModuleTierIndex < ingestModuleTiers.size()) { + return ingestModuleTiers.get(currentModuleTierIndex).getDataSourceIngestPipeline(); + } + return Optional.empty(); + } + /** * Gets a snapshot of some basic diagnostic statistics for the ingest job @@ -1431,7 +1483,12 @@ final class IngestJobExecutor { */ boolean fileIngestRunning = false; Date fileIngestStartTime = null; - for (FileIngestPipeline pipeline : ingestModuleTiers.get(moduleTierIndex).getFileIngestPipelines()) { + Optional> fileIngestPipelines = getCurrentFileIngestPipelines(); + if (!fileIngestPipelines.isPresent()) { + // If there are no currently running pipelines, use the original set. + fileIngestPipelines = Optional.of(ingestModuleTiers.get(0).getFileIngestPipelines()); + } + for (FileIngestPipeline pipeline : fileIngestPipelines.get()) { if (pipeline.isRunning()) { fileIngestRunning = true; } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/AnalysisResultNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/AnalysisResultNode.java index d4568146ed..a63f26e05a 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/AnalysisResultNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/AnalysisResultNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutorService; import java.util.logging.Level; import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; @@ -55,8 +56,8 @@ public class AnalysisResultNode extends ArtifactNode getAnalysisResultType() { return Optional.ofNullable(this.getItemData().getSearchParams().getArtifactType()); } + + @Override + public Optional getDataSourceIdForActions() { + return Optional.ofNullable(this.getItemData().getSearchParams().getDataSourceId()); + } + + @Override + public Optional getNodeSpecificActions() { + ActionsFactory.ActionGroup group = new ActionsFactory.ActionGroup(); + + Optional type = getAnalysisResultType(); + Optional dsId = getDataSourceIdForActions(); + if (type.isPresent()) { + group.add(new DeleteAnalysisResultSetAction(type.get(), "", dsId.isPresent() ? dsId.get() : null)); + } + + return Optional.of(group); + } } @@ -324,6 +344,20 @@ public class AnalysisResultTypeFactory extends TreeChildFactory getAnalysisResultConfigurations() { return Collections.singletonList(this.getItemData().getSearchParams().getConfiguration()); } + + @Override + public Optional getNodeSpecificActions() { + ActionsFactory.ActionGroup group = new ActionsFactory.ActionGroup(); + + Optional type = getAnalysisResultType(); + Optional configuration = getAnalysisResultConfiguration(); + Optional dsId = getDataSourceIdForActions(); + if (type.isPresent()) { + group.add(new DeleteAnalysisResultSetAction(type.get(), configuration.isPresent() ? configuration.get() : "", dsId.isPresent() ? dsId.get() : null)); + } + + return Optional.of(group); + } } /** @@ -541,6 +575,16 @@ public class AnalysisResultTypeFactory extends TreeChildFactory getNodeSpecificActions() { + ActionsFactory.ActionGroup group = new ActionsFactory.ActionGroup(); + KeywordSearchTermParams searchTermParams = this.getItemData().getSearchParams(); + + // ELTODO fill this stub when implementing KWS result deletion + // group.add(new DeleteAnalysisResultSetAction(searchTermParams)); + + return Optional.of(group); + } + public Optional getDataSourceIdForActions() { return Optional.ofNullable(this.getItemData().getSearchParams().getDataSourceId()); } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/ArtifactNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/ArtifactNode.java index acb444962f..97dd3a8b2e 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/ArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/ArtifactNode.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutorService; import javax.swing.Action; import org.apache.commons.lang3.tuple.Pair; import org.openide.nodes.Children; @@ -63,8 +64,8 @@ public abstract class ArtifactNode columns; private Node parentFileNode; - ArtifactNode(SearchResultsDTO searchResults, R rowData, List columns, Lookup lookup, String iconPath) { - super(Children.LEAF, lookup, searchResults, rowData); + ArtifactNode(SearchResultsDTO searchResults, R rowData, List columns, Lookup lookup, String iconPath, ExecutorService backgroundTasksPool) { + super(Children.LEAF, lookup, searchResults, rowData, backgroundTasksPool); this.rowData = rowData; this.columns = columns; setupNodeDisplay(iconPath); diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/BaseNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/BaseNode.java index 12f97536b8..06db5fa7eb 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/BaseNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/BaseNode.java @@ -18,7 +18,6 @@ */ package org.sleuthkit.autopsy.mainui.nodes; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.lang.ref.WeakReference; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -28,7 +27,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.stream.Collectors; import javax.swing.Action; @@ -36,7 +34,6 @@ import javax.swing.SwingUtilities; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Sheet; -import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.openide.util.WeakListeners; @@ -60,9 +57,6 @@ import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.Content; import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; -import org.sleuthkit.datamodel.AnalysisResult; -import org.sleuthkit.datamodel.DataArtifact; -import org.sleuthkit.datamodel.TskCoreException; /** * A a simple starting point for nodes. @@ -144,22 +138,15 @@ abstract class BaseNode extend * A pool of background tasks to run any long computation needed to populate * this node. */ - static final ExecutorService backgroundTasksPool; - private static final Integer MAX_POOL_SIZE = 10; + private final ExecutorService backgroundTasksPool; private FutureTask scoFutureTask; - static { - //Initialize this pool only once! This will be used by every instance BaseNode - //to do their heavy duty SCO column and translation updates. - backgroundTasksPool = Executors.newFixedThreadPool(MAX_POOL_SIZE, - new ThreadFactoryBuilder().setNameFormat("BaseNode-background-task-%d").build()); - } - - BaseNode(Children children, Lookup lookup, S results, R rowData) { + BaseNode(Children children, Lookup lookup, S results, R rowData, ExecutorService backgroundTasksPool) { super(children, lookup); this.results = results; this.rowData = rowData; + this.backgroundTasksPool = backgroundTasksPool; // If the S column is there register the listeners. if (results.getColumns().stream().map(p -> p.getDisplayName()).collect(Collectors.toList()).contains(SCOUtils.SCORE_COLUMN_NAME)) { @@ -218,7 +205,7 @@ abstract class BaseNode extend scoFutureTask = null; } - if ((scoFutureTask == null || scoFutureTask.isDone()) && this instanceof SCOSupporter) { + if ((backgroundTasksPool != null && !backgroundTasksPool.isShutdown() && !backgroundTasksPool.isTerminated()) && (scoFutureTask == null || scoFutureTask.isDone()) && this instanceof SCOSupporter) { scoFutureTask = new FutureTask<>(new SCOFetcher<>(new WeakReference<>((SCOSupporter) this)), ""); backgroundTasksPool.submit(scoFutureTask); } @@ -318,4 +305,8 @@ abstract class BaseNode extend public Action getPreferredAction() { return DirectoryTreeTopComponent.getOpenChildAction(getName()); } + + protected ExecutorService getTaskPool() { + return backgroundTasksPool; + } } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/BlackboardArtifactTagNode.java index c78626e496..c248a3fa1a 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/BlackboardArtifactTagNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes; import java.text.MessageFormat; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutorService; import java.util.logging.Level; import java.util.logging.Logger; import org.openide.nodes.Children; @@ -54,8 +55,8 @@ public final class BlackboardArtifactTagNode extends BaseNode i * @param results The search result DTO. * @param row The table row DTO. */ - public DirectoryNode(SearchResultsDTO results, DirectoryRowDTO row) { - super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row); + public DirectoryNode(SearchResultsDTO results, DirectoryRowDTO row, ExecutorService backgroundTasksPool) { + super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row, backgroundTasksPool); setName(ContentNodeUtil.getContentName(row.getContent().getId())); setDisplayName(ContentNodeUtil.getContentDisplayName(row.getContent().getName())); setShortDescription(ContentNodeUtil.getContentDisplayName(row.getContent().getName())); diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/FileNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/FileNode.java index df7da0c097..af012061ff 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/FileNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/FileNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutorService; import java.util.logging.Level; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; @@ -69,13 +70,13 @@ public class FileNode extends BaseNode implements private final FileRowDTO fileData; private final List columns; - public FileNode(SearchResultsDTO results, FileRowDTO file) { - this(results, file, true); + public FileNode(SearchResultsDTO results, FileRowDTO file, ExecutorService backgroundTasksPool) { + this(results, file, true, backgroundTasksPool); } - public FileNode(SearchResultsDTO results, FileRowDTO file, boolean directoryBrowseMode) { + public FileNode(SearchResultsDTO results, FileRowDTO file, boolean directoryBrowseMode, ExecutorService backgroundTasksPool) { // GVDTODO: at some point, this leaf will need to allow for children - super(Children.LEAF, ContentNodeUtil.getLookup(file.getAbstractFile()), results, file); + super(Children.LEAF, ContentNodeUtil.getLookup(file.getAbstractFile()), results, file, backgroundTasksPool); setIcon(file); setName(ContentNodeUtil.getContentName(file.getId())); setDisplayName(ContentNodeUtil.getContentDisplayName(file.getFileName())); @@ -266,8 +267,8 @@ public class FileNode extends BaseNode implements private final LayoutFileRowDTO layoutFileRow; - public LayoutFileNode(SearchResultsDTO results, LayoutFileRowDTO file) { - super(results, file, true); + public LayoutFileNode(SearchResultsDTO results, LayoutFileRowDTO file, ExecutorService backgroundTasksPool) { + super(results, file, true, backgroundTasksPool); layoutFileRow = file; } @@ -296,8 +297,8 @@ public class FileNode extends BaseNode implements */ public static class SlackFileNode extends FileNode { - public SlackFileNode(SearchResultsDTO results, SlackFileRowDTO file) { - super(results, file); + public SlackFileNode(SearchResultsDTO results, SlackFileRowDTO file, ExecutorService backgroundTasksPool) { + super(results, file, backgroundTasksPool); } @Override diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/ImageNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/ImageNode.java index 6b47a0f911..69434ba4f9 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/ImageNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/ImageNode.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutorService; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.openide.util.NbBundle; @@ -42,8 +43,8 @@ public class ImageNode extends BaseNode implement * @param results The search result DTO. * @param row The table row DTO. */ - public ImageNode(SearchResultsDTO results, ImageRowDTO row) { - super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row); + public ImageNode(SearchResultsDTO results, ImageRowDTO row, ExecutorService backgroundTasksPool) { + super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row, backgroundTasksPool); setName(ContentNodeUtil.getContentName(row.getContent().getId())); setDisplayName(row.getContent().getName()); setShortDescription(row.getContent().getName()); diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/OsAccountNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/OsAccountNode.java index c19384d856..fe40d799c6 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/OsAccountNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/OsAccountNode.java @@ -22,6 +22,7 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutorService; import java.util.stream.Collectors; import java.util.concurrent.FutureTask; import java.util.logging.Level; @@ -43,7 +44,6 @@ import org.sleuthkit.autopsy.datamodel.TskContentItem; import org.sleuthkit.autopsy.mainui.datamodel.ContentRowDTO.OsAccountRowDTO; import org.sleuthkit.autopsy.mainui.datamodel.OsAccountsDAO; import org.sleuthkit.autopsy.mainui.datamodel.SearchResultsDTO; -import static org.sleuthkit.autopsy.mainui.nodes.BaseNode.backgroundTasksPool; import org.sleuthkit.autopsy.mainui.sco.SCOSupporter; import org.sleuthkit.autopsy.mainui.sco.SCOUtils; import org.sleuthkit.datamodel.Content; @@ -64,11 +64,12 @@ public class OsAccountNode extends BaseNode i private FutureTask realmFutureTask = null; - public OsAccountNode(SearchResultsDTO results, OsAccountRowDTO rowData) { + public OsAccountNode(SearchResultsDTO results, OsAccountRowDTO rowData, ExecutorService backgroundTasksPool) { super(Children.LEAF, Lookups.fixed(rowData.getContent(), new TskContentItem<>(rowData.getContent())), results, - rowData); + rowData, + backgroundTasksPool); String name = rowData.getContent().getName(); setName(ContentNodeUtil.getContentName(rowData.getContent().getId())); setDisplayName(name); @@ -112,9 +113,10 @@ public class OsAccountNode extends BaseNode i realmFutureTask = null; } - if ((realmFutureTask == null || realmFutureTask.isDone())) { + ExecutorService threadPool = getTaskPool(); + if ((threadPool != null && !threadPool.isShutdown() && !threadPool.isTerminated()) && (realmFutureTask == null || realmFutureTask.isDone())) { realmFutureTask = new FutureTask<>(new RealmFetcher<>(new WeakReference<>(this)), ""); - backgroundTasksPool.submit(realmFutureTask); + threadPool.submit(realmFutureTask); } } @Override diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/PoolNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/PoolNode.java index eb06894862..45f2915d47 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/PoolNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/PoolNode.java @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.mainui.nodes; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutorService; import org.openide.nodes.Children; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -40,10 +41,10 @@ public class PoolNode extends BaseNode implements * @param results Search Result DTO. * @param row Pool table row DTO. */ - public PoolNode(SearchResultsDTO results, PoolRowDTO row) { + public PoolNode(SearchResultsDTO results, PoolRowDTO row, ExecutorService backgroundTasksPool) { super(Children.LEAF, Lookups.fixed(row.getContent(), new TskContentItem<>(row.getContent())), - results, row); + results, row, backgroundTasksPool); String name = row.getContent().getType().getName(); setName(ContentNodeUtil.getContentName(row.getContent().getId())); diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/SearchResultChildFactory.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/SearchResultChildFactory.java index 44c1440001..53caef9ad8 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/SearchResultChildFactory.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/SearchResultChildFactory.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.mainui.nodes; import java.text.MessageFormat; import java.util.List; import java.util.Objects; +import java.util.concurrent.ExecutorService; import java.util.logging.Level; import java.util.stream.Collectors; import org.openide.nodes.ChildFactory; @@ -60,9 +61,12 @@ public class SearchResultChildFactory extends ChildFactory { private static final Logger logger = Logger.getLogger(SearchResultChildFactory.class.getName()); private SearchResultsDTO results; + + private final ExecutorService nodeThreadPool; - public SearchResultChildFactory(SearchResultsDTO initialResults) { + public SearchResultChildFactory(SearchResultsDTO initialResults, ExecutorService nodeThreadPool) { this.results = initialResults; + this.nodeThreadPool = nodeThreadPool; } @Override @@ -85,37 +89,37 @@ public class SearchResultChildFactory extends ChildFactory { String typeId = key.getRow().getTypeId(); try { if (DataArtifactRowDTO.getTypeIdForClass().equals(typeId)) { - return new DataArtifactNode((DataArtifactTableSearchResultsDTO) key.getSearchResults(), (DataArtifactRowDTO) key.getRow()); + return new DataArtifactNode((DataArtifactTableSearchResultsDTO) key.getSearchResults(), (DataArtifactRowDTO) key.getRow(), nodeThreadPool); } else if (FileRowDTO.getTypeIdForClass().equals(typeId)) { - return new FileNode(key.getSearchResults(), (FileRowDTO) key.getRow(), true); + return new FileNode(key.getSearchResults(), (FileRowDTO) key.getRow(), true, nodeThreadPool); } else if (AnalysisResultRowDTO.getTypeIdForClass().equals(typeId)) { - return new AnalysisResultNode((AnalysisResultTableSearchResultsDTO) key.getSearchResults(), (AnalysisResultRowDTO) key.getRow()); + return new AnalysisResultNode((AnalysisResultTableSearchResultsDTO) key.getSearchResults(), (AnalysisResultRowDTO) key.getRow(), nodeThreadPool); } else if (ContentTagsRowDTO.getTypeIdForClass().equals(typeId)) { - return new ContentTagNode(key.getSearchResults(), (ContentTagsRowDTO) key.getRow()); + return new ContentTagNode(key.getSearchResults(), (ContentTagsRowDTO) key.getRow(), nodeThreadPool); } else if (BlackboardArtifactTagsRowDTO.getTypeIdForClass().equals(typeId)) { - return new BlackboardArtifactTagNode(key.getSearchResults(), (BlackboardArtifactTagsRowDTO) key.getRow()); + return new BlackboardArtifactTagNode(key.getSearchResults(), (BlackboardArtifactTagsRowDTO) key.getRow(), nodeThreadPool); } else if (ImageRowDTO.getTypeIdForClass().equals(typeId)) { - return new ImageNode(key.getSearchResults(), (ImageRowDTO) key.getRow()); + return new ImageNode(key.getSearchResults(), (ImageRowDTO) key.getRow(), nodeThreadPool); } else if (LocalFileDataSourceRowDTO.getTypeIdForClass().equals(typeId)) { - return new LocalFileDataSourceNode(key.getSearchResults(), (LocalFileDataSourceRowDTO) key.getRow()); + return new LocalFileDataSourceNode(key.getSearchResults(), (LocalFileDataSourceRowDTO) key.getRow(), nodeThreadPool); } else if (DirectoryRowDTO.getTypeIdForClass().equals(typeId)) { - return new DirectoryNode(key.getSearchResults(), (DirectoryRowDTO) key.getRow()); + return new DirectoryNode(key.getSearchResults(), (DirectoryRowDTO) key.getRow(), nodeThreadPool); } else if (VolumeRowDTO.getTypeIdForClass().equals(typeId)) { - return new VolumeNode(key.getSearchResults(), (VolumeRowDTO) key.getRow()); + return new VolumeNode(key.getSearchResults(), (VolumeRowDTO) key.getRow(), nodeThreadPool); } else if (LocalDirectoryRowDTO.getTypeIdForClass().equals(typeId)) { - return new LocalDirectoryNode(key.getSearchResults(), (LocalDirectoryRowDTO) key.getRow()); + return new LocalDirectoryNode(key.getSearchResults(), (LocalDirectoryRowDTO) key.getRow(), nodeThreadPool); } else if (VirtualDirectoryRowDTO.getTypeIdForClass().equals(typeId)) { - return new VirtualDirectoryNode(key.getSearchResults(), (VirtualDirectoryRowDTO) key.getRow()); + return new VirtualDirectoryNode(key.getSearchResults(), (VirtualDirectoryRowDTO) key.getRow(), nodeThreadPool); } else if (LayoutFileRowDTO.getTypeIdForClass().equals(typeId)) { - return new LayoutFileNode(key.getSearchResults(), (LayoutFileRowDTO) key.getRow()); + return new LayoutFileNode(key.getSearchResults(), (LayoutFileRowDTO) key.getRow(), nodeThreadPool); } else if (PoolRowDTO.getTypeIdForClass().equals(typeId)) { - return new PoolNode(key.getSearchResults(), (PoolRowDTO) key.getRow()); + return new PoolNode(key.getSearchResults(), (PoolRowDTO) key.getRow(), nodeThreadPool); } else if (SlackFileRowDTO.getTypeIdForClass().equals(typeId)) { - return new SlackFileNode(key.getSearchResults(), (SlackFileRowDTO) key.getRow()); + return new SlackFileNode(key.getSearchResults(), (SlackFileRowDTO) key.getRow(), nodeThreadPool); } else if (OsAccountRowDTO.getTypeIdForClass().equals(typeId)) { - return new OsAccountNode(key.getSearchResults(), (OsAccountRowDTO) key.getRow()); + return new OsAccountNode(key.getSearchResults(), (OsAccountRowDTO) key.getRow(), nodeThreadPool); } else if (CreditCardByFileRowDTO.getTypeIdForClass().equals(typeId)) { - return new CreditCardByFileNode(key.getSearchResults(), (CreditCardByFileRowDTO) key.getRow()); + return new CreditCardByFileNode(key.getSearchResults(), (CreditCardByFileRowDTO) key.getRow(), nodeThreadPool); }else { logger.log(Level.WARNING, MessageFormat.format("No known node for type id: {0} provided by row result: {1}", typeId, key.getRow())); } diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/SearchResultRootNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/SearchResultRootNode.java index eb6db6deaf..2960be87de 100644 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/SearchResultRootNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/SearchResultRootNode.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.mainui.nodes; +import java.util.concurrent.ExecutorService; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Sheet; @@ -38,8 +39,8 @@ public class SearchResultRootNode extends AbstractNode { // therefore is not included in the equals and hashcode methods. private ChildNodeSelectionInfo childNodeSelectionInfo; - public SearchResultRootNode(SearchResultsDTO initialResults) { - this(initialResults, new SearchResultChildFactory(initialResults)); + public SearchResultRootNode(SearchResultsDTO initialResults, ExecutorService nodeThreadPool) { + this(initialResults, new SearchResultChildFactory(initialResults, nodeThreadPool)); } private SearchResultRootNode(SearchResultsDTO initialResults, SearchResultChildFactory factory) { diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/SpecialDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/SpecialDirectoryNode.java index 1543e89af0..d8f8ffdbdd 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/SpecialDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/SpecialDirectoryNode.java @@ -18,9 +18,9 @@ */ package org.sleuthkit.autopsy.mainui.nodes; -import java.lang.ref.WeakReference; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutorService; import org.openide.nodes.Children; import org.openide.nodes.Node; import org.sleuthkit.autopsy.datamodel.NodeProperty; @@ -45,8 +45,8 @@ abstract class SpecialDirectoryNode extends BaseNode row) { - super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row); + private SpecialDirectoryNode(SearchResultsDTO results, ContentRowDTO row, ExecutorService backgroundTasksPool) { + super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row, backgroundTasksPool); setName(ContentNodeUtil.getContentName(row.getContent().getId())); setDisplayName(row.getContent().getName()); setShortDescription(row.getContent().getName()); @@ -105,8 +105,8 @@ abstract class SpecialDirectoryNode extends BaseNode impleme * @param results The search result DTO. * @param row The table row DTO. */ - public VolumeNode(SearchResultsDTO results, VolumeRowDTO row) { - super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row); + public VolumeNode(SearchResultsDTO results, VolumeRowDTO row, ExecutorService backgroundTasksPool) { + super(Children.LEAF, ContentNodeUtil.getLookup(row.getContent()), results, row, backgroundTasksPool); setIconBaseWithExtension(NodeIconUtil.VOLUME.getPath()); //NON-NLS // use first cell value for display name diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/ActionsFactory.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/ActionsFactory.java index 4e7abf4da8..be9c1b360c 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/ActionsFactory.java +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/ActionsFactory.java @@ -61,9 +61,10 @@ import org.sleuthkit.autopsy.directorytree.ExportCSVAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExternalViewerShortcutAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; -import org.sleuthkit.autopsy.directorytree.FileSearchAction; +import org.sleuthkit.autopsy.directorytree.FileSearchTreeAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; import org.sleuthkit.autopsy.directorytree.ViewContextAction; +import org.sleuthkit.autopsy.filesearch.FileSearchAction; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.RunIngestModulesAction; import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; @@ -173,26 +174,6 @@ public final class ActionsFactory { actionGroups.add(new ActionGroup(new ExtractArchiveWithPasswordAction(optionalFile.get()))); } - Optional analysisResultType = actionContext.getAnalysisResultType(); - if (analysisResultType.isPresent() && actionContext.hasAnalysisResultConfigurations()) { - Optional dataSourceId = actionContext.getDataSourceIdForActions(); - - actionGroups.add(new ActionGroup(new AbstractAction("Delete Analysis Results of Type") { - @Override - public void actionPerformed(ActionEvent e) { - List configurations = actionContext.getAnalysisResultConfigurations(); - - JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), - MessageFormat.format("Stub Action for deleting analysis result type: {0} with configurations [{1}] and data source of {2}", - analysisResultType.get().getDisplayName(), - configurations.stream().map(c -> c == null ? "" : "\"" + c + "\"").collect(Collectors.joining(",")), - dataSourceId.map(d -> Long.toString(d)).orElse("")), - "Deleting...", - JOptionPane.WARNING_MESSAGE); - } - })); - } - List actionList = new ArrayList<>(); for (ActionGroup aGroup : actionGroups) { if (aGroup != null) { @@ -511,7 +492,7 @@ public final class ActionsFactory { ActionGroup group = new ActionGroup(); Optional optional = context.getDataSourceForActions(); if(optional.isPresent()) { - group.add(new FileSearchAction(Bundle.ActionFactory_openFileSearchByAttr_text(), optional.get().getId())); + group.add(new FileSearchTreeAction(Bundle.ActionFactory_openFileSearchByAttr_text(), optional.get().getId())); group.add(new ViewSummaryInformationAction(optional.get().getId())); group.add(new RunIngestModulesAction(Collections.singletonList(optional.get()))); group.add(new DeleteDataSourceAction(optional.get().getId())); @@ -522,7 +503,7 @@ public final class ActionsFactory { if(optional.isPresent()) { if (optional.get() instanceof AbstractFile) { if(context.supportsFileSearchAction()) { - group.add(new FileSearchAction(Bundle.ActionFactory_openFileSearchByAttr_text(), optional.get().getId())); + group.add(new FileSearchTreeAction(Bundle.ActionFactory_openFileSearchByAttr_text(), optional.get().getId())); } group.add(new RunIngestModulesAction((AbstractFile)optional.get())); diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/Bundle.properties-MERGED index 4727cacc11..73e116239b 100755 --- a/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/Bundle.properties-MERGED @@ -24,3 +24,15 @@ ArtifactFactory_getViewSrcContentAction_displayName=View Source {0} in Directory # {0} - contentType ArtifactFactory_getViewSrcContentAction_displayName2=View Source {0} DeleteAnalysisResultAction_label=Delete Analysis Result +DeleteAnalysisResultsAction.label=Delete Analysis Results +# {0} - result type +DeleteAnalysisResultsAction.progress.allResults=Deleting Analysis Results type {0} +# {0} - result type +# {1} - configuration +DeleteAnalysisResultsAction.progress.allResultsWithConfiguration=Deleting Analysis Results type {0} and configuration {1} +DeleteAnalysisResultsAction.title=Deleting Analysis Results +# {0} - result type +DeleteAnalysisResultsAction.warning.allResults=Are you sure you want to delete all Analysis Results of type {0}? +# {0} - result type +# {1} - configuration +DeleteAnalysisResultsAction.warning.allResultsWithConfiguration=Are you sure you want to delete all Analysis Results of type {0} and configuration {1}? diff --git a/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/DeleteAnalysisResultSetAction.java b/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/DeleteAnalysisResultSetAction.java new file mode 100755 index 0000000000..2ddf86c80f --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/mainui/nodes/actions/DeleteAnalysisResultSetAction.java @@ -0,0 +1,115 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2022 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed 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.sleuthkit.autopsy.mainui.nodes.actions; + +import java.awt.event.ActionEvent; +import java.util.logging.Level; +import javax.swing.AbstractAction; +import javax.swing.JOptionPane; +import javax.swing.SwingWorker; +import org.openide.util.NbBundle.Messages; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.progress.AppFrameProgressBar; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Action class for Deleting Analysis Result objects. + */ +public class DeleteAnalysisResultSetAction extends AbstractAction { + + @Messages({ + "DeleteAnalysisResultsAction.label=Delete Analysis Results", + "DeleteAnalysisResultsAction.title=Deleting Analysis Results", + "# {0} - result type", + "DeleteAnalysisResultsAction.progress.allResults=Deleting Analysis Results type {0}", + "# {0} - result type", "# {1} - configuration", + "DeleteAnalysisResultsAction.progress.allResultsWithConfiguration=Deleting Analysis Results type {0} and configuration {1}", + "# {0} - result type", + "DeleteAnalysisResultsAction.warning.allResults=Are you sure you want to delete all Analysis Results of type {0}?", + "# {0} - result type", "# {1} - configuration", + "DeleteAnalysisResultsAction.warning.allResultsWithConfiguration=Are you sure you want to delete all Analysis Results of type {0} and configuration {1}?" + }) + + private static final Logger logger = Logger.getLogger(DeleteAnalysisResultSetAction.class.getName()); + private static final long serialVersionUID = 1L; + + private final BlackboardArtifact.Type type; + private final String configuration; + private final Long dsID; + + public DeleteAnalysisResultSetAction(BlackboardArtifact.Type type, String configuration, Long dsID) { + super(Bundle.DeleteAnalysisResultsAction_label()); + this.type = type; + this.configuration = configuration; + this.dsID = dsID; + } + + @Override + public void actionPerformed(ActionEvent e) { + + String warningMessage; + String progressMessage; + if (configuration == null || configuration.isEmpty()) { + warningMessage = Bundle.DeleteAnalysisResultsAction_warning_allResults(type.getDisplayName()); + progressMessage = Bundle.DeleteAnalysisResultsAction_progress_allResults(type.getDisplayName()); + } else { + warningMessage = Bundle.DeleteAnalysisResultsAction_warning_allResultsWithConfiguration(type.getDisplayName(), configuration); + progressMessage = Bundle.DeleteAnalysisResultsAction_progress_allResultsWithConfiguration(type.getDisplayName(), configuration); + } + int response = JOptionPane.showConfirmDialog( + WindowManager.getDefault().getMainWindow(), + warningMessage, + Bundle.DeleteAnalysisResultsAction_title(), + JOptionPane.YES_NO_OPTION); + if (response != JOptionPane.YES_OPTION) { + return; + } + + SwingWorker worker = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + + AppFrameProgressBar progress = new AppFrameProgressBar(Bundle.DeleteAnalysisResultsAction_title()); + try { + progress.start(progressMessage); + progress.switchToIndeterminate(progressMessage); + if (!isCancelled()) { + try { + logger.log(Level.INFO, "Deleting Analysis Results type = {0}, data source ID = {1}, configuration = {2}", new Object[]{type, dsID, configuration}); + Case.getCurrentCase().getSleuthkitCase().getBlackboard().deleteAnalysisResults(type, dsID, configuration); + logger.log(Level.INFO, "Deleted Analysis Results type = {0}, data source ID = {1}, configuration = {2}", new Object[]{type, dsID, configuration}); + } catch (TskCoreException ex) { + logger.log(Level.SEVERE, "Failed to delete analysis results of type = "+type+", data source ID = "+dsID+", configuration = "+configuration, ex); + } + } + + return null; + } finally { + progress.finish(); + } + } + }; + + worker.execute(); + } +} diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java index 06f367d691..c998128d63 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ALeappAnalyzerIngestModule.java @@ -70,9 +70,8 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { private static final String ALEAPP_FS = "fs_"; //NON-NLS private static final String ALEAPP_EXECUTABLE = "aleapp.exe";//NON-NLS private static final String ALEAPP_PATHS_FILE = "aLeapp_paths.txt"; //NON-NLS - - private static final String XMLFILE = "aleap-artifact-attribute-reference.xml"; //NON-NLS + private static final String XMLFILE = "aleap-artifact-attribute-reference.xml"; //NON-NLS private File aLeappExecutable; @@ -118,8 +117,8 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { @NbBundle.Messages({ "ALeappAnalyzerIngestModule.error.running.aLeapp=Error running aLeapp, see log file.", "ALeappAnalyzerIngestModule.error.creating.output.dir=Error creating aLeapp module output directory.", - "ALeappAnalyzerIngestModule.starting.aLeapp=Starting aLeapp", "ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp", + "ALeappAnalyzerIngestModule_processing_aLeapp_results=Processing aLeapp results", "ALeappAnalyzerIngestModule.has.run=aLeapp", "ALeappAnalyzerIngestModule.aLeapp.cancelled=aLeapp run was canceled", "ALeappAnalyzerIngestModule.completed=aLeapp Processing Completed", @@ -127,51 +126,62 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { @Override public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) { + statusHelper.switchToIndeterminate(); + statusHelper.progress(Bundle.ALeappAnalyzerIngestModule_running_aLeapp()); + Case currentCase = Case.getCurrentCase(); Path tempOutputPath = Paths.get(currentCase.getTempDirectory(), ALEAPP, ALEAPP_FS + dataSource.getId()); try { Files.createDirectories(tempOutputPath); } catch (IOException ex) { logger.log(Level.SEVERE, String.format("Error creating aLeapp output directory %s", tempOutputPath.toString()), ex); + writeErrorMsgToIngestInbox(); return ProcessResult.ERROR; } - List aLeappPathsToProcess = new ArrayList<>(); + List aLeappPathsToProcess; ProcessBuilder aLeappCommand = buildaLeappListCommand(tempOutputPath); try { int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); if (result != 0) { logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search for result is %d", result)); + writeErrorMsgToIngestInbox(); return ProcessResult.ERROR; } aLeappPathsToProcess = loadIleappPathFile(tempOutputPath); + if (aLeappPathsToProcess.isEmpty()) { + logger.log(Level.SEVERE, String.format("Error getting file paths to search, list is empty")); + writeErrorMsgToIngestInbox(); + return ProcessResult.ERROR; + } } catch (IOException ex) { logger.log(Level.SEVERE, String.format("Error when trying to execute aLeapp program getting file paths to search"), ex); + writeErrorMsgToIngestInbox(); return ProcessResult.ERROR; } - statusHelper.progress(Bundle.ALeappAnalyzerIngestModule_starting_aLeapp(), 0); - - List aLeappFilesToProcess = new ArrayList<>(); - - if (!(context.getDataSource() instanceof LocalFilesDataSource)) { - extractFilesFromImage(dataSource, aLeappPathsToProcess, tempOutputPath); - statusHelper.switchToDeterminate(aLeappFilesToProcess.size()); - processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); - } else { - aLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource); - statusHelper.switchToDeterminate(aLeappFilesToProcess.size()); - - Integer filesProcessedCount = 0; - for (AbstractFile aLeappFile : aLeappFilesToProcess) { - processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile); - filesProcessedCount++; + if ((context.getDataSource() instanceof LocalFilesDataSource)) { + /* + * The data source may be local files from an iOS file system, or it + * may be a tarred/ZIP of an iOS file system. If it is the latter, + * extract the files we need to process. + */ + List aLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource); + if (!aLeappFilesToProcess.isEmpty()) { + statusHelper.switchToDeterminate(aLeappFilesToProcess.size()); + Integer filesProcessedCount = 0; + for (AbstractFile aLeappFile : aLeappFilesToProcess) { + processALeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, aLeappFile); + filesProcessedCount++; + } } - // Process the logical image as a fs in aLeapp to make sure this is not a logical fs that was added - extractFilesFromImage(dataSource, aLeappPathsToProcess, tempOutputPath); - processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); } + statusHelper.switchToIndeterminate(); + statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_processing_iLeapp_results()); + extractFilesFromDataSource(dataSource, aLeappPathsToProcess, tempOutputPath); + processALeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); + IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, Bundle.ALeappAnalyzerIngestModule_has_run(), Bundle.ALeappAnalyzerIngestModule_completed()); @@ -181,14 +191,17 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { /** * Process a file from a logical image using the aLeapp program - * @param dataSource datasource to process - * @param currentCase current case that is being worked on - * @param statusHelper show progress and update what is being processed + * + * @param dataSource datasource to process + * @param currentCase current case that is being worked on + * @param statusHelper show progress and update what is being + * processed * @param filesProcessedCount number of files that have been processed - * @param aLeappFile the abstract file to process + * @param aLeappFile the abstract file to process */ private void processALeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, AbstractFile aLeappFile) { + statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount); String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime); try { @@ -198,7 +211,6 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { return; } - statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.file", aLeappFile.getName()), filesProcessedCount); ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, aLeappFile.getLocalAbsPath(), aLeappFile.getNameExtension()); try { int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); @@ -219,21 +231,20 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { return; } - ProcessResult fileProcessorResult = aLeappFileProcessor.processFiles(dataSource, moduleOutputPath, aLeappFile); - - if (fileProcessorResult == ProcessResult.ERROR) { - return; - } + aLeappFileProcessor.processFiles(dataSource, moduleOutputPath, aLeappFile); } /** * Process a image/directory using the aLeapp program - * @param dataSource datasource to process - * @param currentCase current case being procesed - * @param statusHelper show progress and update what is being processed + * + * @param dataSource datasource to process + * @param currentCase current case being procesed + * @param statusHelper show progress and update what is being + * processed * @param directoryToProcess directory to run aLeapp against */ private void processALeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess) { + statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.filesystem")); String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ALEAPP, currentTime); try { @@ -243,7 +254,6 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { return; } - statusHelper.progress(NbBundle.getMessage(this.getClass(), "ALeappAnalyzerIngestModule.processing.filesystem")); ProcessBuilder aLeappCommand = buildaLeappCommand(moduleOutputPath, directoryToProcess, "fs"); try { int result = ExecUtil.execute(aLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); @@ -264,23 +274,16 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { return; } - ProcessResult fileProcessorResult = aLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath); - - if (fileProcessorResult == ProcessResult.ERROR) { - return; - } - + aLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath); } - - /** * Build the aLeapp command to run - * - * @param moduleOutputPath output path for the aLeapp program. - * @param sourceFilePath where the source files to process reside. + * + * @param moduleOutputPath output path for the aLeapp program. + * @param sourceFilePath where the source files to process reside. * @param aLeappFileSystemType the filesystem type to process - * + * * @return the command to execute */ private ProcessBuilder buildaLeappCommand(Path moduleOutputPath, String sourceFilePath, String aLeappFileSystemType) { @@ -311,8 +314,8 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) { ProcessBuilder processBuilder = new ProcessBuilder(commandLine); /* - * Add an environment variable to force aLeapp to run with - * the same permissions Autopsy uses. + * Add an environment variable to force aLeapp to run with the same + * permissions Autopsy uses. */ processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS return processBuilder; @@ -335,7 +338,7 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { private void addILeappReportToReports(Path aLeappOutputDir, Case currentCase) { List allIndexFiles = new ArrayList<>(); - try (Stream walk = Files.walk(aLeappOutputDir)) { + try (Stream walk = Files.walk(aLeappOutputDir)) { allIndexFiles = walk.map(x -> x.toString()) .filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList()); @@ -380,7 +383,7 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { return aLeappPathsToProcess; } - private void extractFilesFromImage(Content dataSource, List aLeappPathsToProcess, Path moduleOutputPath) { + private void extractFilesFromDataSource(Content dataSource, List aLeappPathsToProcess, Path moduleOutputPath) { FileManager fileManager = getCurrentCase().getServices().getFileManager(); for (String fullFilePath : aLeappPathsToProcess) { @@ -418,33 +421,33 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { private void extractFileToOutput(Content dataSource, AbstractFile aLeappFile, File fileParentPath, Path parentPath) { if (fileParentPath.exists()) { - if (!aLeappFile.isDir()) { - writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString()); - } else { - try { - Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName())); - } catch (IOException ex) { - logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); - } - } - } else { - try { - Files.createDirectories(parentPath); - } catch (IOException ex) { - logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); - } - if (!aLeappFile.isDir()) { - writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString()); - } else { - try { - Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName())); - } catch (IOException ex) { - logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); - } - } + if (!aLeappFile.isDir()) { + writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString()); + } else { + try { + Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName())); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); } + } + } else { + try { + Files.createDirectories(parentPath); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); + } + if (!aLeappFile.isDir()) { + writeaLeappFile(dataSource, aLeappFile, fileParentPath.toString()); + } else { + try { + Files.createDirectories(Paths.get(parentPath.toString(), aLeappFile.getName())); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating aLeapp output directory %s", parentPath.toString()), ex); + } + } + } } - + private void writeaLeappFile(Content dataSource, AbstractFile aLeappFile, String parentPath) { String fileName = aLeappFile.getName().replace(":", "-"); if (!fileName.matches(".") && !fileName.matches("..") && !fileName.toLowerCase().endsWith("-slack")) { @@ -461,4 +464,16 @@ public class ALeappAnalyzerIngestModule implements DataSourceIngestModule { } } } + + /** + * Writes a generic error message to the ingest inbox, directing the user to + * consult the application log fpor more details. + */ + private void writeErrorMsgToIngestInbox() { + IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.ERROR, + MODULE_NAME, + Bundle.ALeappAnalyzerIngestModule_error_running_aLeapp()); + IngestServices.getInstance().postMessage(message); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED index a07ed802be..a1d45fa3ad 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED @@ -8,7 +8,7 @@ ALeappAnalyzerIngestModule.has.run=aLeapp ALeappAnalyzerIngestModule.report.name=aLeapp Html Report ALeappAnalyzerIngestModule.requires.windows=aLeapp module requires windows. ALeappAnalyzerIngestModule.running.aLeapp=Running aLeapp -ALeappAnalyzerIngestModule.starting.aLeapp=Starting aLeapp +ALeappAnalyzerIngestModule_processing_aLeapp_results=Processing aLeapp results ALeappAnalyzerModuleFactory_moduleDesc=Uses aLEAPP to analyze logical acquisitions of Android devices. ALeappAnalyzerModuleFactory_moduleName=Android Analyzer (aLEAPP) ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed @@ -31,7 +31,7 @@ AleappAnalyzerIngestModule.not.64.bit.os=aLeapp will not run on a 32bit operatin ILeappAnalyzerIngestModule.report.name=iLeapp Html Report ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows. ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp -ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp +ILeappAnalyzerIngestModule_processing_iLeapp_results=Processing iLeapp results ILeappAnalyzerModuleFactory_moduleDesc=Uses iLEAPP to analyze logical acquisitions of iOS devices. ILeappAnalyzerModuleFactory_moduleName=iOS Analyzer (iLEAPP) LeappFileProcessor.cannot.create.calllog.relationship=Cannot create TSK_CALLLOG Relationship. diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java index c3afd036d8..5e2365d38b 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/ILeappAnalyzerIngestModule.java @@ -73,7 +73,6 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { private static final String XMLFILE = "ileap-artifact-attribute-reference.xml"; //NON-NLS - private File iLeappExecutable; private IngestJobContext context; @@ -95,7 +94,7 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { if (false == PlatformUtil.is64BitOS()) { throw new IngestModuleException(NbBundle.getMessage(this.getClass(), "IleappAnalyzerIngestModule.not.64.bit.os")); } - + if (false == PlatformUtil.isWindowsOS()) { throw new IngestModuleException(Bundle.ILeappAnalyzerIngestModule_requires_windows()); } @@ -118,8 +117,8 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { @NbBundle.Messages({ "ILeappAnalyzerIngestModule.error.running.iLeapp=Error running iLeapp, see log file.", "ILeappAnalyzerIngestModule.error.creating.output.dir=Error creating iLeapp module output directory.", - "ILeappAnalyzerIngestModule.starting.iLeapp=Starting iLeapp", "ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp", + "ILeappAnalyzerIngestModule_processing_iLeapp_results=Processing iLeapp results", "ILeappAnalyzerIngestModule.has.run=iLeapp", "ILeappAnalyzerIngestModule.iLeapp.cancelled=iLeapp run was canceled", "ILeappAnalyzerIngestModule.completed=iLeapp Processing Completed", @@ -127,51 +126,62 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { @Override public ProcessResult process(Content dataSource, DataSourceIngestModuleProgress statusHelper) { + statusHelper.switchToIndeterminate(); + statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_running_iLeapp()); + Case currentCase = Case.getCurrentCase(); Path tempOutputPath = Paths.get(currentCase.getTempDirectory(), ILEAPP, ILEAPP_FS + dataSource.getId()); try { Files.createDirectories(tempOutputPath); } catch (IOException ex) { logger.log(Level.SEVERE, String.format("Error creating iLeapp output directory %s", tempOutputPath.toString()), ex); + writeErrorMsgToIngestInbox(); return ProcessResult.ERROR; } - List iLeappPathsToProcess = new ArrayList<>(); + List iLeappPathsToProcess; ProcessBuilder iLeappCommand = buildiLeappListCommand(tempOutputPath); try { int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); if (result != 0) { logger.log(Level.SEVERE, String.format("Error when trying to execute iLeapp program getting file paths to search for result is %d", result)); + writeErrorMsgToIngestInbox(); return ProcessResult.ERROR; } iLeappPathsToProcess = loadIleappPathFile(tempOutputPath); + if (iLeappPathsToProcess.isEmpty()) { + logger.log(Level.SEVERE, String.format("Error getting file paths to search, list is empty")); + writeErrorMsgToIngestInbox(); + return ProcessResult.ERROR; + } } catch (IOException ex) { logger.log(Level.SEVERE, String.format("Error when trying to execute iLeapp program getting file paths to search"), ex); + writeErrorMsgToIngestInbox(); return ProcessResult.ERROR; } - statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_starting_iLeapp(), 0); - - List iLeappFilesToProcess = new ArrayList<>(); - - if (!(context.getDataSource() instanceof LocalFilesDataSource)) { - extractFilesFromImage(dataSource, iLeappPathsToProcess, tempOutputPath); - statusHelper.switchToDeterminate(iLeappFilesToProcess.size()); - processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); - } else { - iLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource); - statusHelper.switchToDeterminate(iLeappFilesToProcess.size()); - - Integer filesProcessedCount = 0; - for (AbstractFile iLeappFile : iLeappFilesToProcess) { - processILeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, iLeappFile); - filesProcessedCount++; + if ((context.getDataSource() instanceof LocalFilesDataSource)) { + /* + * The data source may be local files from an iOS file system, or it + * may be a tarred/ZIP of an iOS file system. If it is the latter, + * extract the files we need to process. + */ + List iLeappFilesToProcess = LeappFileProcessor.findLeappFilesToProcess(dataSource); + if (!iLeappFilesToProcess.isEmpty()) { + statusHelper.switchToDeterminate(iLeappFilesToProcess.size()); + Integer filesProcessedCount = 0; + for (AbstractFile iLeappFile : iLeappFilesToProcess) { + processILeappFile(dataSource, currentCase, statusHelper, filesProcessedCount, iLeappFile); + filesProcessedCount++; + } } - // Process the logical image as a fs in iLeapp to make sure this is not a logical fs that was added - extractFilesFromImage(dataSource, iLeappPathsToProcess, tempOutputPath); - processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); } + statusHelper.switchToIndeterminate(); + statusHelper.progress(Bundle.ILeappAnalyzerIngestModule_processing_iLeapp_results()); + extractFilesFromDataSource(dataSource, iLeappPathsToProcess, tempOutputPath); + processILeappFs(dataSource, currentCase, statusHelper, tempOutputPath.toString()); + IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, Bundle.ILeappAnalyzerIngestModule_has_run(), Bundle.ILeappAnalyzerIngestModule_completed()); @@ -180,15 +190,19 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { } /** - * Process each tar/zip file that is found in a logical image that contains xLeapp data - * @param dataSource Datasource where the file has been found - * @param currentCase current case - * @param statusHelper Progress bar for messages to show user + * Process each tar/zip file that is found in a logical image that contains + * xLeapp data + * + * @param dataSource Datasource where the file has been found + * @param currentCase current case + * @param statusHelper Progress bar for messages to show user * @param filesProcessedCount count that is incremented for progress bar - * @param iLeappFile abstract file that will be processed + * @param iLeappFile abstract file that will be processed */ private void processILeappFile(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, int filesProcessedCount, AbstractFile iLeappFile) { + statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.file", iLeappFile.getName()), filesProcessedCount); + String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ILEAPP, currentTime); try { @@ -198,7 +212,6 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { return; } - statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.file", iLeappFile.getName()), filesProcessedCount); ProcessBuilder iLeappCommand = buildiLeappCommand(moduleOutputPath, iLeappFile.getLocalAbsPath(), iLeappFile.getNameExtension()); try { int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); @@ -219,21 +232,19 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { return; } - ProcessResult fileProcessorResult = iLeappFileProcessor.processFiles(dataSource, moduleOutputPath, iLeappFile); - - if (fileProcessorResult == ProcessResult.ERROR) { - return; - } + iLeappFileProcessor.processFiles(dataSource, moduleOutputPath, iLeappFile); } /** * Process extracted files from a disk image using xLeapp - * @param dataSource Datasource where the file has been found - * @param currentCase current case - * @param statusHelper Progress bar for messages to show user - * @param directoryToProcess + * + * @param dataSource Datasource where the file has been found + * @param currentCase current case + * @param statusHelper Progress bar for messages to show user + * @param directoryToProcess */ private void processILeappFs(Content dataSource, Case currentCase, DataSourceIngestModuleProgress statusHelper, String directoryToProcess) { + statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.filesystem")); String currentTime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss z", Locale.US).format(System.currentTimeMillis());//NON-NLS Path moduleOutputPath = Paths.get(currentCase.getModuleDirectory(), ILEAPP, currentTime); try { @@ -243,7 +254,6 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { return; } - statusHelper.progress(NbBundle.getMessage(this.getClass(), "ILeappAnalyzerIngestModule.processing.filesystem")); ProcessBuilder iLeappCommand = buildiLeappCommand(moduleOutputPath, directoryToProcess, "fs"); try { int result = ExecUtil.execute(iLeappCommand, new DataSourceIngestModuleProcessTerminator(context, true)); @@ -264,19 +274,16 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { return; } - ProcessResult fileProcessorResult = iLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath); - - if (fileProcessorResult == ProcessResult.ERROR) { - return; - } - + iLeappFileProcessor.processFileSystem(dataSource, moduleOutputPath); } /** * Build the command to run xLeapp - * @param moduleOutputPath output path for xLeapp - * @param sourceFilePath path where the xLeapp file is + * + * @param moduleOutputPath output path for xLeapp + * @param sourceFilePath path where the xLeapp file is * @param iLeappFileSystemType type of file to process tar/zip/fs + * * @return process to run */ private ProcessBuilder buildiLeappCommand(Path moduleOutputPath, String sourceFilePath, String iLeappFileSystemType) { @@ -294,7 +301,9 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { /** * Command to run xLeapp using the path option + * * @param moduleOutputPath path where the file paths output will reside + * * @return process to run */ private ProcessBuilder buildiLeappListCommand(Path moduleOutputPath) { @@ -311,8 +320,8 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { static private ProcessBuilder buildProcessWithRunAsInvoker(String... commandLine) { ProcessBuilder processBuilder = new ProcessBuilder(commandLine); /* - * Add an environment variable to force iLeapp to run with - * the same permissions Autopsy uses. + * Add an environment variable to force iLeapp to run with the same + * permissions Autopsy uses. */ processBuilder.environment().put("__COMPAT_LAYER", "RunAsInvoker"); //NON-NLS return processBuilder; @@ -335,7 +344,7 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { private void addILeappReportToReports(Path iLeappOutputDir, Case currentCase) { List allIndexFiles; - try (Stream walk = Files.walk(iLeappOutputDir)) { + try (Stream walk = Files.walk(iLeappOutputDir)) { allIndexFiles = walk.map(x -> x.toString()) .filter(f -> f.toLowerCase().endsWith("index.html")).collect(Collectors.toList()); @@ -383,11 +392,12 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { /** * Extract files from a disk image to process with xLeapp - * @param dataSource Datasource of the image - * @param iLeappPathsToProcess List of paths to extract content from - * @param moduleOutputPath path to write content to + * + * @param dataSource Datasource of the image + * @param iLeappPathsToProcess List of paths to extract content from + * @param moduleOutputPath path to write content to */ - private void extractFilesFromImage(Content dataSource, List iLeappPathsToProcess, Path moduleOutputPath) { + private void extractFilesFromDataSource(Content dataSource, List iLeappPathsToProcess, Path moduleOutputPath) { FileManager fileManager = getCurrentCase().getServices().getFileManager(); for (String fullFilePath : iLeappPathsToProcess) { @@ -425,42 +435,44 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { /** * Create path and file from datasource in temp - * @param dataSource datasource of the image - * @param iLeappFile abstract file to write out + * + * @param dataSource datasource of the image + * @param iLeappFile abstract file to write out * @param fileParentPath parent file path - * @param parentPath parent file + * @param parentPath parent file */ private void extractFileToOutput(Content dataSource, AbstractFile iLeappFile, File fileParentPath, Path parentPath) { if (fileParentPath.exists()) { - if (!iLeappFile.isDir()) { - writeiLeappFile(dataSource, iLeappFile, fileParentPath.toString()); - } else { - try { - Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName())); - } catch (IOException ex) { - logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex); - } - } - } else { - try { - Files.createDirectories(parentPath); - } catch (IOException ex) { - logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex); - } - if (!iLeappFile.isDir()) { - writeiLeappFile(dataSource, iLeappFile, fileParentPath.toString()); - } else { - try { - Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName())); - } catch (IOException ex) { - logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex); - } - } + if (!iLeappFile.isDir()) { + writeiLeappFile(dataSource, iLeappFile, fileParentPath.toString()); + } else { + try { + Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName())); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex); } + } + } else { + try { + Files.createDirectories(parentPath); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex); + } + if (!iLeappFile.isDir()) { + writeiLeappFile(dataSource, iLeappFile, fileParentPath.toString()); + } else { + try { + Files.createDirectories(Paths.get(parentPath.toString(), iLeappFile.getName())); + } catch (IOException ex) { + logger.log(Level.INFO, String.format("Error creating iLeapp output directory %s", parentPath.toString()), ex); + } + } + } } - + /** * Write out file to output + * * @param dataSource datasource of disk image * @param iLeappFile acstract file to write out * @param parentPath path to write file to @@ -481,4 +493,16 @@ public class ILeappAnalyzerIngestModule implements DataSourceIngestModule { } } } + + /** + * Writes a generic error message to the ingest inbox, directing the user to + * consult the application log fpor more details. + */ + private void writeErrorMsgToIngestInbox() { + IngestMessage message = IngestMessage.createMessage(IngestMessage.MessageType.ERROR, + MODULE_NAME, + Bundle.ILeappAnalyzerIngestModule_error_running_iLeapp()); + IngestServices.getInstance().postMessage(message); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/progress/SilentProgressIndicator.java b/Core/src/org/sleuthkit/autopsy/progress/SilentProgressIndicator.java index c7ed9c671c..97692a8adb 100644 --- a/Core/src/org/sleuthkit/autopsy/progress/SilentProgressIndicator.java +++ b/Core/src/org/sleuthkit/autopsy/progress/SilentProgressIndicator.java @@ -18,8 +18,6 @@ */ package org.sleuthkit.autopsy.progress; -import org.sleuthkit.autopsy.progress.ProgressIndicator; - /** * A "silent" or "null" progress indicator. */ diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index eb38792032..65e740fc47 100644 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -42,8 +42,8 @@ file.reference.javassist-3.12.1.GA.jar=release/modules/ext/javassist-3.12.1.GA.j file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0-r4.jar file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar -file.reference.jna-5.9.0.jar=release/modules/ext/jna-5.10.0.jar -file.reference.jna-platform-5.9.0.jar=release/modules/ext/jna-platform-5.10.0.jar +file.reference.jna-5.10.0.jar=release/modules/ext/jna-5.10.0.jar +file.reference.jna-platform-5.10.0.jar=release/modules/ext/jna-platform-5.10.0.jar file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java index 7fbc80a2a2..d4f789a861 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/autoingest/AutoIngestManager.java @@ -2814,10 +2814,13 @@ final class AutoIngestManager extends Observable implements PropertyChangeListen /* * Block until notified by the ingest job event listener * or until interrupted because auto ingest is shutting - * down. + * down. For very small jobs, it is possible that ingest has + * completed by the time we get here, so check periodically + * in case the event was missed. */ - ingestLock.wait(); - sysLogger.log(Level.INFO, "Finished ingest modules analysis for {0} ", manifestPath); + while (IngestManager.getInstance().isIngestRunning()) { + ingestLock.wait(300000); // Check every five minutes + } IngestJob.ProgressSnapshot jobSnapshot = ingestJob.getSnapshot(); IngestJob.ProgressSnapshot.DataSourceProcessingSnapshot snapshot = jobSnapshot.getDataSourceProcessingSnapshot(); AutoIngestJobLogger nestedJobLogger = new AutoIngestJobLogger(manifestPath, snapshot.getDataSource(), caseDirectoryPath); diff --git a/InternalPythonModules/android/contact.py b/InternalPythonModules/android/contact.py index 5d5e181fdd..2ebd744eb1 100644 --- a/InternalPythonModules/android/contact.py +++ b/InternalPythonModules/android/contact.py @@ -158,7 +158,7 @@ class ContactAnalyzer(general.AndroidComponentAnalyzer): phoneNumber, # phoneNumber, None, # homePhoneNumber, None, # mobilePhoneNumber, - emailAddr, context.getJobId()) # emailAddr + emailAddr) # emailAddr except SQLException as ex: self._logger.log(Level.WARNING, "Error processing query result for Android messages.", ex) diff --git a/KeywordSearch/ivy.xml b/KeywordSearch/ivy.xml index 2bc97f2078..db2f503672 100644 --- a/KeywordSearch/ivy.xml +++ b/KeywordSearch/ivy.xml @@ -16,10 +16,10 @@ - + - + diff --git a/KeywordSearch/nbproject/project.properties b/KeywordSearch/nbproject/project.properties index a1d9beaf83..df914dd442 100644 --- a/KeywordSearch/nbproject/project.properties +++ b/KeywordSearch/nbproject/project.properties @@ -44,8 +44,7 @@ file.reference.poi-scratchpad-4.0.1.jar=release/modules/ext/poi-scratchpad-4.0.1 file.reference.protobuf-java-2.5.0.jar=release/modules/ext/protobuf-java-2.5.0.jar file.reference.quartz-2.2.0.jar=release/modules/ext/quartz-2.2.0.jar file.reference.slf4j-api-1.7.25.jar=release/modules/ext/slf4j-api-1.7.25.jar -file.reference.solr-solrj-8.6.2.jar=release/modules/ext/solr-solrj-8.6.2.jar -file.reference.solr-solrj-8.6.3.jar=release/modules/ext/solr-solrj-8.6.3.jar +file.reference.solr-solrj-8.11.1.jar=release/modules/ext/solr-solrj-8.11.1.jar file.reference.sqlwrapper-0.0.1.jar=release/modules/ext/sqlwrapper-0.0.1.jar file.reference.stax2-api-3.1.4.jar=release/modules/ext/stax2-api-3.1.4.jar file.reference.tagsoup-1.2.1.jar=release/modules/ext/tagsoup-1.2.1.jar @@ -57,7 +56,7 @@ file.reference.vorbis-java-tika-0.8.jar=release/modules/ext/vorbis-java-tika-0.8 file.reference.woodstox-core-asl-4.4.1.jar=release/modules/ext/woodstox-core-asl-4.4.1.jar file.reference.xmlbeans-2.6.0.jar=release/modules/ext/xmlbeans-2.6.0.jar file.reference.xmpcore-5.1.3.jar=release/modules/ext/xmpcore-5.1.3.jar -file.reference.zookeeper-3.5.7.jar=release/modules/ext/zookeeper-3.5.7.jar +file.reference.zookeeper-3.6.2.jar=release/modules/ext/zookeeper-3.6.2.jar file.reference.annotations-12.0.jar=release\\modules\\ext\\annotations-12.0.jar file.reference.jsonic-1.2.11.jar=release\\modules\\ext\\jsonic-1.2.11.jar javac.source=1.8 @@ -66,5 +65,5 @@ license.file=../LICENSE-2.0.txt nbm.homepage=http://www.sleuthkit.org/autopsy/ nbm.needs.restart=true source.reference.commons-validator-1.5.1.jar=release/modules/ext/commons-validator-1.5.1-sources.jar -source.reference.solr-solrj-8.6.2.jar=release/modules/ext/solr-solrj-8.6.2-sources.jar +source.reference.solr-solrj-8.11.1.jar=release/modules/ext/solr-solrj-8.11.1-sources.jar spec.version.base=6.6 diff --git a/KeywordSearch/nbproject/project.xml b/KeywordSearch/nbproject/project.xml index 1a1760e572..6a3345927e 100644 --- a/KeywordSearch/nbproject/project.xml +++ b/KeywordSearch/nbproject/project.xml @@ -357,8 +357,8 @@ release/modules/ext/poi-ooxml-schemas-4.0.1.jar - ext/zookeeper-3.5.7.jar - release/modules/ext/zookeeper-3.5.7.jar + ext/zookeeper-3.6.2.jar + release/modules/ext/zookeeper-3.6.2.jar ext/commons-collections-3.2.2.jar @@ -385,8 +385,8 @@ release/modules/ext/httpclient-4.5.10.jar - ext/solr-solrj-8.6.3.jar - release/modules/ext/solr-solrj-8.6.3.jar + ext/solr-solrj-8.11.1.jar + release/modules/ext/solr-solrj-8.11.1.jar ext/vorbis-java-tika-0.8.jar diff --git a/KeywordSearch/solr/server/README.txt b/KeywordSearch/solr/server/README.txt index d4b421cac3..bfdbc611fe 100755 --- a/KeywordSearch/solr/server/README.txt +++ b/KeywordSearch/solr/server/README.txt @@ -93,8 +93,8 @@ statements in the solrconfig.xml file to reference plugin jars outside of this directory for loading "contrib" plugins via relative paths. If you make a copy of this example server and wish to use the -ExtractingRequestHandler (SolrCell), DataImportHandler (DIH), the -clustering component, or any other modules in "contrib", you will need to +ExtractingRequestHandler (SolrCell), DataImportHandler (DIH), +or any other modules in "contrib", you will need to copy the required jars or update the paths to those jars in your solrconfig.xml. diff --git a/KeywordSearch/solr/server/etc/jetty-gzip.xml b/KeywordSearch/solr/server/etc/jetty-gzip.xml new file mode 100755 index 0000000000..cb69edd9f6 --- /dev/null +++ b/KeywordSearch/solr/server/etc/jetty-gzip.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KeywordSearch/solr/server/etc/jetty.xml b/KeywordSearch/solr/server/etc/jetty.xml index ecd4f220fe..e2f4ab0959 100755 --- a/KeywordSearch/solr/server/etc/jetty.xml +++ b/KeywordSearch/solr/server/etc/jetty.xml @@ -93,7 +93,7 @@ - * + /solr/* Content-Security-Policy default-src 'none'; base-uri 'none'; connect-src 'self'; form-action 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self'; media-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; worker-src 'self'; @@ -102,7 +102,7 @@ - * + /solr/* X-Content-Type-Options nosniff @@ -111,7 +111,7 @@ - * + /solr/* X-Frame-Options SAMEORIGIN @@ -120,7 +120,7 @@ - * + /solr/* X-XSS-Protection 1; mode=block diff --git a/KeywordSearch/solr/server/etc/security.policy b/KeywordSearch/solr/server/etc/security.policy index bcf82b9eb2..7716da090a 100755 --- a/KeywordSearch/solr/server/etc/security.policy +++ b/KeywordSearch/solr/server/etc/security.policy @@ -103,6 +103,9 @@ grant { permission java.lang.RuntimePermission "writeFileDescriptor"; // needed by hadoop http permission java.lang.RuntimePermission "getProtectionDomain"; + // needed by aws s3 sdk (Apache HTTP Client) + permission java.lang.RuntimePermission "setFactory"; + permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.reflect"; // These two *have* to be spelled out a separate permission java.lang.management.ManagementPermission "control"; @@ -198,6 +201,11 @@ grant { permission java.io.FilePermission "${log4j.configurationFile}", "read,write,delete,readlink"; + // Credentials for S3 Repository + permission java.io.FilePermission "${aws.sharedCredentialsFile}", "read,readlink"; + permission java.io.FilePermission "${aws.configFile}", "read,readlink"; + permission java.io.FilePermission "${user.home}${/}.aws${/}-", "read,readlink"; + // expanded to a wildcard if set, allows all networking everywhere permission java.net.SocketPermission "${solr.internal.network.permission}", "accept,listen,connect,resolve"; }; diff --git a/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.13.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.13.2.jar deleted file mode 100755 index d0e6b7fffe..0000000000 Binary files a/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.13.2.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.16.0.jar b/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.16.0.jar new file mode 100755 index 0000000000..90033d419a Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.16.0.jar differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-api-2.13.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-api-2.13.2.jar deleted file mode 100755 index afc89ff0d5..0000000000 Binary files a/KeywordSearch/solr/server/lib/ext/log4j-api-2.13.2.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-api-2.16.0.jar b/KeywordSearch/solr/server/lib/ext/log4j-api-2.16.0.jar new file mode 100755 index 0000000000..2fea718f26 Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-api-2.16.0.jar differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-core-2.13.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-core-2.13.2.jar deleted file mode 100755 index 9b6bdff8e2..0000000000 Binary files a/KeywordSearch/solr/server/lib/ext/log4j-core-2.13.2.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-core-2.16.0.jar b/KeywordSearch/solr/server/lib/ext/log4j-core-2.16.0.jar new file mode 100755 index 0000000000..6a2365bab8 Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-core-2.16.0.jar differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-layout-template-json-2.16.0.jar b/KeywordSearch/solr/server/lib/ext/log4j-layout-template-json-2.16.0.jar new file mode 100755 index 0000000000..4c0155251b Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-layout-template-json-2.16.0.jar differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.13.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.13.2.jar deleted file mode 100755 index 19e257cae8..0000000000 Binary files a/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.13.2.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.16.0.jar b/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.16.0.jar new file mode 100755 index 0000000000..84a3fad098 Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.16.0.jar differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-web-2.13.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-web-2.13.2.jar deleted file mode 100755 index c96dc2e238..0000000000 Binary files a/KeywordSearch/solr/server/lib/ext/log4j-web-2.13.2.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/ext/log4j-web-2.16.0.jar b/KeywordSearch/solr/server/lib/ext/log4j-web-2.16.0.jar new file mode 100755 index 0000000000..c9fcd95b38 Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-web-2.16.0.jar differ diff --git a/KeywordSearch/solr/server/lib/http2-common-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/http2-common-9.4.27.v20200227.jar deleted file mode 100755 index d42399fdef..0000000000 Binary files a/KeywordSearch/solr/server/lib/http2-common-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/http2-common-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/http2-common-9.4.44.v20210927.jar new file mode 100755 index 0000000000..b1354d5c8f Binary files /dev/null and b/KeywordSearch/solr/server/lib/http2-common-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/http2-hpack-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/http2-hpack-9.4.44.v20210927.jar similarity index 59% rename from KeywordSearch/solr/server/lib/http2-hpack-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/lib/http2-hpack-9.4.44.v20210927.jar index ef55bbe988..1f7ebf8d96 100755 Binary files a/KeywordSearch/solr/server/lib/http2-hpack-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/lib/http2-hpack-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/http2-server-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/http2-server-9.4.27.v20200227.jar deleted file mode 100755 index fa355943cd..0000000000 Binary files a/KeywordSearch/solr/server/lib/http2-server-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/http2-server-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/http2-server-9.4.44.v20210927.jar new file mode 100755 index 0000000000..9416e81a37 Binary files /dev/null and b/KeywordSearch/solr/server/lib/http2-server-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.44.v20210927.jar similarity index 72% rename from KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.44.v20210927.jar index 5f743e760a..613db3774b 100755 Binary files a/KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.44.v20210927.jar similarity index 76% rename from KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.44.v20210927.jar index 0adfdc73ba..a39a3d19bd 100755 Binary files a/KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-continuation-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-continuation-9.4.44.v20210927.jar similarity index 74% rename from KeywordSearch/solr/server/lib/jetty-continuation-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/lib/jetty-continuation-9.4.44.v20210927.jar index dea8a52d3c..1c76828e5d 100755 Binary files a/KeywordSearch/solr/server/lib/jetty-continuation-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/lib/jetty-continuation-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-deploy-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-deploy-9.4.44.v20210927.jar similarity index 51% rename from KeywordSearch/solr/server/lib/jetty-deploy-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/lib/jetty-deploy-9.4.44.v20210927.jar index ab33050a82..3dc0e82313 100755 Binary files a/KeywordSearch/solr/server/lib/jetty-deploy-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/lib/jetty-deploy-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-http-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-http-9.4.27.v20200227.jar deleted file mode 100755 index 556a76be5a..0000000000 Binary files a/KeywordSearch/solr/server/lib/jetty-http-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/jetty-http-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/jetty-http-9.4.44.v20210927.jar new file mode 100755 index 0000000000..c894e87fdc Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-http-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-io-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-io-9.4.27.v20200227.jar deleted file mode 100755 index 375f825188..0000000000 Binary files a/KeywordSearch/solr/server/lib/jetty-io-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/jetty-io-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/jetty-io-9.4.44.v20210927.jar new file mode 100755 index 0000000000..afdcfd5300 Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-io-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-jmx-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-jmx-9.4.44.v20210927.jar similarity index 70% rename from KeywordSearch/solr/server/lib/jetty-jmx-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/lib/jetty-jmx-9.4.44.v20210927.jar index 522c13ef3a..6568ef004a 100755 Binary files a/KeywordSearch/solr/server/lib/jetty-jmx-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/lib/jetty-jmx-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-rewrite-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-rewrite-9.4.44.v20210927.jar similarity index 66% rename from KeywordSearch/solr/server/lib/jetty-rewrite-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/lib/jetty-rewrite-9.4.44.v20210927.jar index b9c20ff800..cda7e7195b 100755 Binary files a/KeywordSearch/solr/server/lib/jetty-rewrite-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/lib/jetty-rewrite-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-security-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-security-9.4.44.v20210927.jar similarity index 50% rename from KeywordSearch/solr/server/lib/jetty-security-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/lib/jetty-security-9.4.44.v20210927.jar index 4ee129b4e0..01fd9d2cb6 100755 Binary files a/KeywordSearch/solr/server/lib/jetty-security-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/lib/jetty-security-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-server-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-server-9.4.27.v20200227.jar deleted file mode 100755 index 5185014cbc..0000000000 Binary files a/KeywordSearch/solr/server/lib/jetty-server-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/jetty-server-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/jetty-server-9.4.44.v20210927.jar new file mode 100755 index 0000000000..42e709dcfc Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-server-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-servlet-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-servlet-9.4.27.v20200227.jar deleted file mode 100755 index 4ea397d55d..0000000000 Binary files a/KeywordSearch/solr/server/lib/jetty-servlet-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/jetty-servlet-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/jetty-servlet-9.4.44.v20210927.jar new file mode 100755 index 0000000000..82b91c1632 Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-servlet-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-servlets-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-servlets-9.4.27.v20200227.jar deleted file mode 100755 index 5a8d07c4f4..0000000000 Binary files a/KeywordSearch/solr/server/lib/jetty-servlets-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/jetty-servlets-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/jetty-servlets-9.4.44.v20210927.jar new file mode 100755 index 0000000000..8ff90f54c1 Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-servlets-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-util-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-util-9.4.27.v20200227.jar deleted file mode 100755 index 6b53df4c07..0000000000 Binary files a/KeywordSearch/solr/server/lib/jetty-util-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/jetty-util-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/jetty-util-9.4.44.v20210927.jar new file mode 100755 index 0000000000..a3229c00fb Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-util-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-webapp-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-webapp-9.4.27.v20200227.jar deleted file mode 100755 index 234bf2f64b..0000000000 Binary files a/KeywordSearch/solr/server/lib/jetty-webapp-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/jetty-webapp-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/jetty-webapp-9.4.44.v20210927.jar new file mode 100755 index 0000000000..a78a9c751c Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-webapp-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/lib/jetty-xml-9.4.27.v20200227.jar b/KeywordSearch/solr/server/lib/jetty-xml-9.4.27.v20200227.jar deleted file mode 100755 index 859888805d..0000000000 Binary files a/KeywordSearch/solr/server/lib/jetty-xml-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/lib/jetty-xml-9.4.44.v20210927.jar b/KeywordSearch/solr/server/lib/jetty-xml-9.4.44.v20210927.jar new file mode 100755 index 0000000000..86ded266ec Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-xml-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/modules/gzip.mod b/KeywordSearch/solr/server/modules/gzip.mod new file mode 100755 index 0000000000..3542a45fda --- /dev/null +++ b/KeywordSearch/solr/server/modules/gzip.mod @@ -0,0 +1,12 @@ +[description] +Enable GzipHandler for dynamic gzip compression +for the entire server. + +[tags] +handler + +[depend] +server + +[xml] +etc/jetty-gzip.xml diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/apiguardian-api-1.1.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/apiguardian-api-1.1.0.jar new file mode 100755 index 0000000000..e6fcead36f Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/apiguardian-api-1.1.0.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-7.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-7.2.jar deleted file mode 100755 index 5058db4fa5..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-7.2.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-8.0.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-8.0.1.jar new file mode 100755 index 0000000000..744fecc025 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-8.0.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-7.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-7.2.jar deleted file mode 100755 index bb84f3a9d5..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-7.2.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-8.0.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-8.0.1.jar new file mode 100755 index 0000000000..42a44d5b6a Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-8.0.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.13.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.18.0.jar similarity index 58% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.13.0.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.18.0.jar index a508768422..e9f7b50dff 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.13.0.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.18.0.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.8.4.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.8.4.jar deleted file mode 100755 index 96cac37c51..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.8.4.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.9.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.9.2.jar new file mode 100755 index 0000000000..0b40451f51 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.9.2.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.18.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.18.0.jar deleted file mode 100755 index a814080a28..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.18.0.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.27.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.27.0.jar new file mode 100755 index 0000000000..6fd409c8e3 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.27.0.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.18.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.18.0.jar deleted file mode 100755 index dc5002d5bd..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.18.0.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.27.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.27.0.jar new file mode 100755 index 0000000000..246622a908 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.27.0.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/checker-qual-3.10.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/checker-qual-3.10.0.jar new file mode 100755 index 0000000000..9bab003254 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/checker-qual-3.10.0.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-collections4-4.4.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-collections4-4.4.jar new file mode 100755 index 0000000000..da06c3e4ba Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-collections4-4.4.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.6.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.6.jar deleted file mode 100755 index 00556b119d..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.6.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.8.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.8.0.jar new file mode 100755 index 0000000000..177e58dc65 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.8.0.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang-2.6.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang-2.6.jar new file mode 100755 index 0000000000..98467d3a65 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang-2.6.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.10.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.10.jar new file mode 100755 index 0000000000..e51c729bad Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.10.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.9.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.9.jar deleted file mode 100755 index 0d89693926..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.9.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/esri-geometry-api-2.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/esri-geometry-api-2.2.0.jar new file mode 100755 index 0000000000..178671a7d1 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/esri-geometry-api-2.2.0.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.2.jar similarity index 50% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.0.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.2.jar index 0a52d1b6d4..74c7b6079d 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.0.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.2.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.2.jar similarity index 54% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.0.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.2.jar index 683f3f7d1a..cc582a739a 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.0.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.2.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.2.jar similarity index 59% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.0.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.2.jar index 77a00c750c..858eda7520 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.0.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.2.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.2.jar similarity index 64% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.0.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.2.jar index 59afc3eaf6..a9f78e995e 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.0.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.2.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.27.v20200227.jar deleted file mode 100755 index 058e9033fa..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.44.v20210927.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.44.v20210927.jar new file mode 100755 index 0000000000..01031f047c Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.27.v20200227.jar deleted file mode 100755 index d42399fdef..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.44.v20210927.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.44.v20210927.jar new file mode 100755 index 0000000000..b1354d5c8f Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.44.v20210927.jar similarity index 59% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.44.v20210927.jar index ef55bbe988..1f7ebf8d96 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.27.v20200227.jar deleted file mode 100755 index aedb3e38a0..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.44.v20210927.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.44.v20210927.jar new file mode 100755 index 0000000000..7a292aa0ab Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.10.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.13.jar similarity index 71% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.10.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.13.jar index d0c7821c82..218ee25f2b 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.10.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.13.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.12.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.14.jar similarity index 75% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.12.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.14.jar index 1838672ac3..349db181c3 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.12.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.14.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.10.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.13.jar similarity index 80% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.10.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.13.jar index 0fae6d0542..cc52f44a3a 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.10.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.13.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.10.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.12.3.jar similarity index 51% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.10.1.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.12.3.jar index a10399ce3e..fd71f66d07 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.10.1.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.12.3.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.10.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.10.1.jar deleted file mode 100755 index 1640a4e08f..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.10.1.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.12.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.12.3.jar new file mode 100755 index 0000000000..3062f8fb1c Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.12.3.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.10.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.10.1.jar deleted file mode 100755 index abe3748dbd..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.10.1.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.12.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.12.3.jar new file mode 100755 index 0000000000..47efedfc95 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.12.3.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.10.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.10.1.jar deleted file mode 100755 index 6526f94433..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.10.1.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.12.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.12.3.jar new file mode 100755 index 0000000000..12dc144b38 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.12.3.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.44.v20210927.jar similarity index 76% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.44.v20210927.jar index 0db577f8c5..d7a02e38dc 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.44.v20210927.jar similarity index 73% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.27.v20200227.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.44.v20210927.jar index d09841c8b7..f1076d94b2 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.27.v20200227.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.27.v20200227.jar deleted file mode 100755 index b89cf7fe75..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.44.v20210927.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.44.v20210927.jar new file mode 100755 index 0000000000..b8c4325f3f Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.27.v20200227.jar deleted file mode 100755 index 556a76be5a..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.44.v20210927.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.44.v20210927.jar new file mode 100755 index 0000000000..c894e87fdc Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.27.v20200227.jar deleted file mode 100755 index 375f825188..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.44.v20210927.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.44.v20210927.jar new file mode 100755 index 0000000000..afdcfd5300 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.27.v20200227.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.27.v20200227.jar deleted file mode 100755 index 6b53df4c07..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.27.v20200227.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.44.v20210927.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.44.v20210927.jar new file mode 100755 index 0000000000..a3229c00fb Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.44.v20210927.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.11.1.jar similarity index 85% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.11.1.jar index 09479e7bfa..582716c7e1 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.11.1.jar similarity index 99% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.11.1.jar index b77bc376d8..0987390130 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.11.1.jar similarity index 99% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.11.1.jar index 876475ed18..a7cb1328dc 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.11.1.jar similarity index 76% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.11.1.jar index 731e48d596..9e13c8566b 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.11.1.jar similarity index 82% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.11.1.jar index 882ef6dc16..1874dd5108 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.11.1.jar similarity index 88% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.11.1.jar index 26a5597cf9..63043f63ed 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.11.1.jar similarity index 79% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.11.1.jar index bed07de222..c81f3dc08a 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.11.1.jar similarity index 64% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.11.1.jar index 8cd3f6bdc0..1c5a768d6e 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.11.1.jar similarity index 79% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.11.1.jar index 566bfa1a2c..548a9c244a 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.11.1.jar similarity index 87% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.11.1.jar index 014ec65a0e..3e1cfb9978 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.11.1.jar similarity index 84% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.11.1.jar index 7844c16de9..d18407f5fd 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.11.1.jar similarity index 68% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.11.1.jar index 13ae61da9e..d2204b6025 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.11.1.jar similarity index 83% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.11.1.jar index 5b649100cb..d6b9b27882 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.11.1.jar similarity index 79% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.11.1.jar index 6782e84753..049855a444 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.11.1.jar similarity index 81% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.11.1.jar index 3eba9e9034..3aea1c4946 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.11.1.jar similarity index 82% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.11.1.jar index ac56bbda82..02b9b09744 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.11.1.jar similarity index 72% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.11.1.jar index a718570646..f94d2c1252 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.11.1.jar similarity index 89% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.11.1.jar index bf60088d1f..c1055bad87 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.11.1.jar similarity index 90% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.11.1.jar index 60a3779b67..7dc0664f32 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.11.1.jar similarity index 87% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.11.1.jar index b347e54921..53b562bab4 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-buffer-4.1.47.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-buffer-4.1.47.Final.jar deleted file mode 100755 index e80f769613..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-buffer-4.1.47.Final.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-buffer-4.1.68.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-buffer-4.1.68.Final.jar new file mode 100755 index 0000000000..cb26d98f36 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-buffer-4.1.68.Final.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-codec-4.1.47.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-codec-4.1.68.Final.jar similarity index 56% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-codec-4.1.47.Final.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-codec-4.1.68.Final.jar index 9deb6efd6f..27b88d8f49 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-codec-4.1.47.Final.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-codec-4.1.68.Final.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-common-4.1.47.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-common-4.1.47.Final.jar deleted file mode 100755 index 7efa59345a..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-common-4.1.47.Final.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-common-4.1.68.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-common-4.1.68.Final.jar new file mode 100755 index 0000000000..c313345acb Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-common-4.1.68.Final.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-handler-4.1.47.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-handler-4.1.47.Final.jar deleted file mode 100755 index fb3889ffa8..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-handler-4.1.47.Final.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-handler-4.1.68.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-handler-4.1.68.Final.jar new file mode 100755 index 0000000000..b240bf737d Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-handler-4.1.68.Final.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-resolver-4.1.47.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-resolver-4.1.68.Final.jar similarity index 55% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-resolver-4.1.47.Final.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-resolver-4.1.68.Final.jar index b15d287062..0a129e520e 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-resolver-4.1.47.Final.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-resolver-4.1.68.Final.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-4.1.47.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-4.1.68.Final.jar similarity index 50% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-4.1.47.Final.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-4.1.68.Final.jar index 1aab3d9808..fd55e5d7d8 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-4.1.47.Final.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-4.1.68.Final.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-epoll-4.1.47.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-epoll-4.1.47.Final.jar deleted file mode 100755 index 4e3e83d798..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-epoll-4.1.47.Final.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-epoll-4.1.68.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-epoll-4.1.68.Final.jar new file mode 100755 index 0000000000..29960503d3 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-epoll-4.1.68.Final.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-unix-common-4.1.47.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-unix-common-4.1.47.Final.jar deleted file mode 100755 index 54f63ae2d8..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-unix-common-4.1.47.Final.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-unix-common-4.1.68.Final.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-unix-common-4.1.68.Final.jar new file mode 100755 index 0000000000..5252b3df61 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/netty-transport-native-unix-common-4.1.68.Final.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet-2.4.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet-2.4.3.jar deleted file mode 100755 index 52df9a9f58..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet-2.4.3.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet.ext.servlet-2.4.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet.ext.servlet-2.4.3.jar deleted file mode 100755 index 63c749db29..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet.ext.servlet-2.4.3.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/snappy-java-1.1.7.6.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/snappy-java-1.1.7.6.jar new file mode 100755 index 0000000000..7a3a3cbc09 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/snappy-java-1.1.7.6.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.11.1.jar similarity index 62% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.11.1.jar index ca1feae0ab..2d95ef3672 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.6.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.11.1.jar similarity index 61% rename from KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.6.3.jar rename to KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.11.1.jar index 759a36bd82..966ef0f4f1 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.6.3.jar and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.11.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-3.1.4.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-3.1.4.jar deleted file mode 100755 index dded036928..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-3.1.4.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-4.2.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-4.2.1.jar new file mode 100755 index 0000000000..28c6a08f40 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-4.2.1.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-6.2.4.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-6.2.4.jar new file mode 100755 index 0000000000..b0a8130d4c Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-6.2.4.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-asl-4.4.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-asl-4.4.1.jar deleted file mode 100755 index d8b4e8cf87..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-asl-4.4.1.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.5.7.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.5.7.jar deleted file mode 100755 index 78b2ff9495..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.5.7.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.6.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.6.2.jar new file mode 100755 index 0000000000..0fccefeda2 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.6.2.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.5.7.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.5.7.jar deleted file mode 100755 index 408bbd1973..0000000000 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.5.7.jar and /dev/null differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.6.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.6.2.jar new file mode 100755 index 0000000000..a781c86daf Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.6.2.jar differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/web.xml b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/web.xml index 53ab57abbb..2599420ddb 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/web.xml +++ b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/web.xml @@ -47,25 +47,11 @@ org.apache.solr.servlet.LoadAdminUiServlet - - SolrRestApi - org.restlet.ext.servlet.ServerServlet - - org.restlet.application - org.apache.solr.rest.SolrSchemaRestApi - - - LoadAdminUI /index.html - - SolrRestApi - /schema/* - - .xsl diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/angular-csp.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/angular-csp.css index 4442d0cb5b..476bbb1b3e 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/angular-csp.css +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/angular-csp.css @@ -18,8 +18,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* - AngularJS v1.7.9 - (c) 2010-2018 Google, Inc. http://angularjs.org + AngularJS v1.8.0 + (c) 2010-2020 Google, Inc. http://angularjs.org License: MIT */ /* Include this file in your html if you are using the CSP mode. */ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/collections.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/collections.css index 41f152b7b7..a89fab4716 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/collections.css +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/collections.css @@ -123,6 +123,11 @@ limitations under the License. padding-right: 3px; } +#content #collections .chosen-container.chosen-container-single +{ + width: 100% !important; +} + #content #collections .actions form .buttons { padding-top: 10px; @@ -228,7 +233,7 @@ limitations under the License. #content #collections #data #alias-data h2 { background-image: url( ../../img/ico/box.png ); } #content #collections #data #collection-data h2 { background-image: url( ../../img/ico/box.png ); } #content #collections #data #shard-data h2 { background-image: url( ../../img/ico/sitemap.png ); } -#content #collections #data #shard-data .replica h2 { background-image: url( ../../img/ico/node-slave.png ); } +#content #collections #data #shard-data .replica h2 { background-image: url( ../../img/ico/node-follower.png ); } #content #collections #data #index-data { diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dashboard.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dashboard.css index edfd55657a..bedca16c47 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dashboard.css +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dashboard.css @@ -144,8 +144,8 @@ limitations under the License. #content #dashboard #system h2 { background-image: url( ../../img/ico/server.png ); } #content #dashboard #statistics h2 { background-image: url( ../../img/ico/chart.png ); } #content #dashboard #replication h2 { background-image: url( ../../img/ico/node.png ); } -#content #dashboard #replication.master h2 { background-image: url( ../../img/ico/node-master.png ); } -#content #dashboard #replication.slave h2 { background-image: url( ../../img/ico/node-slave.png ); } +#content #dashboard #replication.leader h2 { background-image: url( ../../img/ico/node-leader.png ); } +#content #dashboard #replication.follower h2 { background-image: url( ../../img/ico/node-follower.png ); } #content #dashboard #instance h2 { background-image: url( ../../img/ico/server.png ); } #content #dashboard #collection h2 { background-image: url( ../../img/ico/book-open-text.png ); } #content #dashboard #shards h2 { background-image: url( ../../img/ico/documents-stack.png ); } diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jstree.style.min.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jstree.style.min.css index 4f60797458..023e51b037 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jstree.style.min.css +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jstree.style.min.css @@ -21,4 +21,4 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:transparent;color:#666666}.jstree-default .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:bold}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top, #beebff 0, #a8e4ff 100%);background:linear-gradient(to bottom, #beebff 0, #a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url("../../img/jstree/32px.png")} .jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y} .jstree-default .jstree-last{background:transparent} .jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px} .jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px} .jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px} .jstree-default .jstree-themeicon{background-position:-260px -4px} .jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px} .jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px} .jstree-default .jstree-disabled{background:transparent} .jstree-default .jstree-disabled.jstree-hovered{background:transparent} .jstree-default .jstree-disabled.jstree-clicked{background:#efefef} .jstree-default .jstree-checkbox{background-position:-164px -4px} .jstree-default .jstree-checkbox:hover{background-position:-164px -36px} .jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px} .jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px} .jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px} .jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px} .jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)} .jstree-default>.jstree-striped{background-size:auto 48px} .jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y} .jstree-default.jstree-rtl .jstree-last{background:transparent} .jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px} .jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px} .jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px} .jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px} .jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px} .jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0} .jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("../../img/jstree/throbber.gif") center center no-repeat} .jstree-default .jstree-file{background:url("../../img/jstree/32px.png") -100px -68px no-repeat} .jstree-default .jstree-folder{background:url("../../img/jstree/32px.png") -260px -4px no-repeat} .jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0} #jstree-dnd.jstree-default{line-height:24px;padding:0 4px} #jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url("../../img/jstree/32px.png");background-repeat:no-repeat;background-color:transparent} #jstree-dnd.jstree-default i{background:transparent;width:24px;height:24px;line-height:24px} #jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px} #jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px} .jstree-default .jstree-ellipsis{overflow:hidden} .jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden} .jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")} .jstree-default.jstree-rtl .jstree-last{background:transparent} .jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px} .jstree-default-small .jstree-anchor{line-height:18px;height:18px} .jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px} .jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px} .jstree-default-small.jstree-rtl .jstree-node{margin-right:18px} .jstree-default-small .jstree-wholerow{height:18px} .jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url("../../img/jstree/32px.png")} .jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y} .jstree-default-small .jstree-last{background:transparent} .jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px} .jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px} .jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px} .jstree-default-small .jstree-themeicon{background-position:-263px -7px} .jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px} .jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px} .jstree-default-small .jstree-disabled{background:transparent} .jstree-default-small .jstree-disabled.jstree-hovered{background:transparent} .jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef} .jstree-default-small .jstree-checkbox{background-position:-167px -7px} .jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px} .jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px} .jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px} .jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px} .jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px} .jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)} .jstree-default-small>.jstree-striped{background-size:auto 36px} .jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y} .jstree-default-small.jstree-rtl .jstree-last{background:transparent} .jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px} .jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px} .jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px} .jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px} .jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px} .jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0} .jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("../../img/jstree/throbber.gif") center center no-repeat} .jstree-default-small .jstree-file{background:url("../../img/jstree/32px.png") -103px -71px no-repeat} .jstree-default-small .jstree-folder{background:url("../../img/jstree/32px.png") -263px -7px no-repeat} .jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0} #jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px} #jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url("../../img/jstree/32px.png");background-repeat:no-repeat;background-color:transparent} #jstree-dnd.jstree-default-small i{background:transparent;width:18px;height:18px;line-height:18px} #jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px} #jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px} .jstree-default-small .jstree-ellipsis{overflow:hidden} .jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden} .jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")} .jstree-default-small.jstree-rtl .jstree-last{background:transparent} .jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px} .jstree-default-large .jstree-anchor{line-height:32px;height:32px} .jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px} .jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px} .jstree-default-large.jstree-rtl .jstree-node{margin-right:32px} .jstree-default-large .jstree-wholerow{height:32px} .jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url("../../img/jstree/32px.png")} .jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y} .jstree-default-large .jstree-last{background:transparent} .jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0} .jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0} .jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0} .jstree-default-large .jstree-themeicon{background-position:-256px 0} .jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0} .jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0} .jstree-default-large .jstree-disabled{background:transparent} .jstree-default-large .jstree-disabled.jstree-hovered{background:transparent} .jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef} .jstree-default-large .jstree-checkbox{background-position:-160px 0} .jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px} .jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0} .jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px} .jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0} .jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px} .jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)} .jstree-default-large>.jstree-striped{background-size:auto 64px} .jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y} .jstree-default-large.jstree-rtl .jstree-last{background:transparent} .jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px} .jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px} .jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px} .jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px} .jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px} .jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0} .jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("../../img/jstree/throbber.gif") center center no-repeat} .jstree-default-large .jstree-file{background:url("../../img/jstree/32px.png") -96px -64px no-repeat} .jstree-default-large .jstree-folder{background:url("../../img/jstree/32px.png") -256px 0 no-repeat} .jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0} #jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px} #jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url("../../img/jstree/32px.png");background-repeat:no-repeat;background-color:transparent} #jstree-dnd.jstree-default-large i{background:transparent;width:32px;height:32px;line-height:32px} #jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px} #jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px} .jstree-default-large .jstree-ellipsis{overflow:hidden} .jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden} .jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")} .jstree-default-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white} #jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px} #jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("../../img/jstree/40px.png");background-position:0 -200px;background-size:120px 240px} #jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("../../img/jstree/40px.png");background-position:-40px -200px;background-size:120px 240px} #jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url("../../img/jstree/40px.png")} .jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap} .jstree-default-responsive .jstree-anchor{line-height:40px;height:40px} .jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px} .jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0} .jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent} .jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0} .jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px} .jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent} .jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important} .jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important} .jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important} .jstree-default-responsive .jstree-themeicon{background-position:-40px -40px} .jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px} .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px} .jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px} .jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white} .jstree-default-responsive>.jstree-striped{background:transparent} .jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px} .jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9} .jstree-default-responsive .jstree-wholerow-clicked{background:#beebff} .jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666666} .jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666666;border-top:0} .jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none} .jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("../../img/jstree/40px.png");background-size:120px 240px} .jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y} .jstree-default-responsive .jstree-last{background:transparent} .jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px} .jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px} .jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0} .jstree-default-responsive .jstree-file{background:url("../../img/jstree/40px.png") 0 -160px no-repeat;background-size:120px 240px} .jstree-default-responsive .jstree-folder{background:url("../../img/jstree/40px.png") -40px -40px no-repeat;background-size:120px 240px} .jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} +.jstree-node,.jstree-children,.jstree-container-ul{display:block;margin:0;padding:0;list-style-type:none;list-style-image:none}.jstree-node{white-space:nowrap}.jstree-anchor{display:inline-block;color:black;white-space:nowrap;padding:0 4px 0 1px;margin:0;vertical-align:top}.jstree-anchor:focus{outline:0}.jstree-anchor,.jstree-anchor:link,.jstree-anchor:visited,.jstree-anchor:hover,.jstree-anchor:active{text-decoration:none;color:inherit}.jstree-icon{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-icon:empty{display:inline-block;text-decoration:none;margin:0;padding:0;vertical-align:top;text-align:center}.jstree-ocl{cursor:pointer}.jstree-leaf>.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:transparent;color:#666666}.jstree-default .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:bold}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top, #beebff 0, #a8e4ff 100%);background:linear-gradient(to bottom, #beebff 0, #a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url("../../img/jstree/32px.png")}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background:transparent}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:transparent}.jstree-default .jstree-disabled.jstree-hovered{background:transparent}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("../../img/jstree/throbber.gif") center center no-repeat}.jstree-default .jstree-file{background:url("../../img/jstree/32px.png") -100px -68px no-repeat}.jstree-default .jstree-folder{background:url("../../img/jstree/32px.png") -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url("../../img/jstree/32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default .jstree-ellipsis{overflow:hidden}.jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 29px);text-overflow:ellipsis;overflow:hidden}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default.jstree-rtl .jstree-last{background:transparent}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url("../../img/jstree/32px.png")}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background:transparent}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:transparent}.jstree-default-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("../../img/jstree/throbber.gif") center center no-repeat}.jstree-default-small .jstree-file{background:url("../../img/jstree/32px.png") -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url("../../img/jstree/32px.png") -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url("../../img/jstree/32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small .jstree-ellipsis{overflow:hidden}.jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 23px);text-overflow:ellipsis;overflow:hidden}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-small.jstree-rtl .jstree-last{background:transparent}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url("../../img/jstree/32px.png")}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background:transparent}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:transparent}.jstree-default-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("../../img/jstree/throbber.gif") center center no-repeat}.jstree-default-large .jstree-file{background:url("../../img/jstree/32px.png") -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url("../../img/jstree/32px.png") -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url("../../img/jstree/32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large .jstree-ellipsis{overflow:hidden}.jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 37px);text-overflow:ellipsis;overflow:hidden}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-large.jstree-rtl .jstree-last{background:transparent}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("../../img/jstree/40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("../../img/jstree/40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url("../../img/jstree/40px.png")}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-responsive>.jstree-striped{background:transparent}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("../../img/jstree/40px.png");background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background:transparent}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url("../../img/jstree/40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url("../../img/jstree/40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}} diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/menu.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/menu.css index b180eaa02a..45b4f5e8d9 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/menu.css +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/menu.css @@ -253,7 +253,7 @@ limitations under the License. #menu #index.global p a { background-image: url( ../../img/ico/dashboard.png ); } -#menu #login.global p a { background-image: url( ../../img/ico/users.png ); } +#menu #login.global p a { background-image: url( ../../img/ico/logout.png ); } #menu #logging.global p a { background-image: url( ../../img/ico/inbox-document-text.png ); } #menu #logging.global .level a { background-image: url( ../../img/ico/gear.png ); } @@ -269,9 +269,12 @@ limitations under the License. #menu #cloud.global p a { background-image: url( ../../img/ico/network-cloud.png ); } #menu #cloud.global .tree a { background-image: url( ../../img/ico/folder-tree.png ); } #menu #cloud.global .nodes a { background-image: url( ../../img/solr-ico.png ); } -#menu #cloud.global .zkstatus a { background-image: url( ../../img/ico/node-master.png ); } +#menu #cloud.global .zkstatus a { background-image: url( ../../img/ico/node-leader.png ); } #menu #cloud.global .graph a { background-image: url( ../../img/ico/molecule.png ); } +#menu #schema-designer.global p a { background-image: url( ../../img/ico/book-open-text.png ); } +#menu #security.global p a { background-image: url( ../../img/ico/users.png ); } + .sub-menu .ping.error a { diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/query.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/query.css index 2f1e81b2ea..34c6be1016 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/query.css +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/query.css @@ -128,16 +128,21 @@ limitations under the License. margin-top: 0; } -#content #query #form fieldset .fieldset +#content #query #form fieldset:not(.optional) .fieldset { border-bottom: 1px solid #f0f0f0; margin-bottom: 5px; padding-bottom: 10px; } +#content #query #form fieldset.optional .fieldset{ + margin-bottom: 5px; + padding-bottom: 10px; +} #content #query #form .optional { - border: 0; + border-top-width: 0; + border-bottom: 1px solid #f0f0f0; } #content #query #form .optional legend diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/replication.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/replication.css index 6cef74e00c..edba6be483 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/replication.css +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/replication.css @@ -61,17 +61,17 @@ limitations under the License. border-bottom: 0; } -#content #replication .masterOnly, -#content #replication .slaveOnly +#content #replication .leaderOnly, +#content #replication .followerOnly { } -#content #replication.master .masterOnly +#content #replication.leader .leaderOnly { display: block; } -#content #replication.slave .slaveOnly +#content #replication.follower .followerOnly { display: block; } @@ -114,8 +114,8 @@ limitations under the License. #content #replication #progress #bar #eta { position: absolute; - right: -100px; - width: 100px; + right: -160px; + width: 160px; } #content #replication #progress #bar #bar-info @@ -300,7 +300,7 @@ limitations under the License. text-align: left; } -#content #replication.slave #details table .slaveOnly +#content #replication.follower #details table .followerOnly { display: table-row; } diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/schema-designer.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/schema-designer.css new file mode 100755 index 0000000000..f1bea2572d --- /dev/null +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/schema-designer.css @@ -0,0 +1,1603 @@ +/* + +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. + +*/ +#content #designer +{ + position: relative; +} + +#content #designer .loader +{ + background-position: 0 50%; + padding-left: 21px; +} + +#content #designer #designer-top +{ + padding: 0px; +} + +#content #designer #tree-content +{ + overflow: auto; + float: left; + height: 520px; + width: 275px; + padding: 3px; +} +#content #designer #tree-node-content +{ + height: 560px; + margin: 2px; + overflow: hidden; +} + +#content #designer .designer-left +{ + float: left; + width: 380px; + min-width: 380px; /* so the text area doesn't bleed over to the right */ + padding: 7px; +} + +#content #designer .designer-middle +{ + float: left; + width: 48%; + padding: 7px; + height: 585px; +} + +#content #designer .designer-right +{ + padding: 7px; + overflow: hidden; +} + +#content #designer .query-tester-left +{ + float: left; + width: 30%; + padding: 7px; +} + +#content #designer .query-tester-right +{ + padding: 7px; + overflow: auto; +} + +#content #designer .data +{ + padding-bottom: 12px; + overflow: hidden; +} + +#content #designer .data:hover +{ + overflow-x: auto; +} + +#content #designer .data li +{ + padding-top: 3px; + padding-bottom: 3px; +} + +#content #designer .data li dt +{ + float: left; + white-space: nowrap; + width: 20%; +} + +#content #designer .data li dd +{ + float: right; + text-overflow: ellipsis; + white-space: nowrap; + width: 80% +} + +#content #designer .data li dd.odd +{ + background-color: #f0f0f0; +} + +#content #designer .data dt span +{ + background-position: 1px 50%; + display: block; + padding-left: 22px; + font-weight: bold; + text-align: left; +} + +#content #designer #sample-docs h2 { background-image: url( ../../img/ico/document-text.png ); } +#content #designer #query-tester h2 { background-image: url( ../../img/ico/magnifier.png ); } +#content #designer #query-results h2 { background-image: url( ../../img/ico/documents-stack.png ); } +#content #designer #schema-editor h2 { background-image: url( ../../img/ico/book-open-text.png ); } +#content #designer #analysis h2 { background-image: url( ../../img/ico/property.png ); } + +#content #designer #form +{ + margin-bottom: 10px; +} + +#content #designer #form label +{ + cursor: pointer; + display: block; + margin-top: 5px; +} + +#content #designer #field-form-left +{ + float: left; + width: 45%; + padding: 7px; +} + +#content #designer #field-form-right +{ + margin-top: 8px; + padding: 7px; + overflow: hidden; +} + +#content #designer .field-form +{ + display: block; + padding: 5px; +} + +#content #designer .field-form-right +{ + display: block; + padding: 5px; +} + +#content #designer .field-form-checkbox { + margin-top: 10px; + margin-left: 130px; + display: block; +} + +#content #designer .field-form-right label +{ + float: left; + padding-top: 3px; + padding-bottom: 3px; + text-align: right; + width: 120px; + margin-right: 6px; +} + +#content #designer #languages +{ + width: 125px; +} + +#content #designer .checkbox +{ + text-align: left; + padding-left: 3px; +} + +#content #designer .actions +{ + margin-bottom: 5px; +} + +#content #designer .actions form .error +{ + background-image: url( ../../img/ico/cross-button.png ); + background-position: 22% 1px; + color: #c00; + font-weight: bold; +} + +#content #designer .actions form p +{ + padding-bottom: 8px; +} + +#content #designer .actions form label +{ + float: left; + padding-top: 3px; + padding-bottom: 3px; + text-align: right; + width: 25%; + margin-right: 6px; +} + +#content #designer .actions #download-button span +{ + background-image: url( ../../img/ico/download-cloud.png ); +} + +#content #designer #schema-selector .left +{ + float: left; + width: 405px; +} + +#content #designer #schema-selector .middle +{ + float: left; + width: 48%; +} + +#content #designer #schema-selector .right +{ + text-align: right; + overflow: hidden; + margin-right: 10px; +} + +#content #designer #schema-selector #apply +{ + float: right; + text-align: right; + width: 300px; +} + +#content #designer #schema-selector a +{ + padding: 0; + padding-left: 8px; +} + +#content #designer #schema-selector select +{ + width: 150px; +} + +#content #designer .actions form input, +#content #designer .actions form select, +#content #designer .actions form .buttons, +#content #designer .actions form .note span +{ + float: right; + width: 71%; +} + +#content #designer .actions form .note span +{ + padding-left: 3px; + padding-right: 3px; +} + +#content #designer .actions form .buttons +{ + padding-top: 10px; +} + +#content #designer .actions form button.submit +{ + margin-right: 20px; +} + +#content #designer .actions form button.submit span +{ + background-image: url( ../../img/ico/tick.png ); +} + +#content #designer .actions form button.reset span +{ + background-image: url( ../../img/ico/cross.png ); +} + +#content #designer .actions #add span +{ + background-image: url( ../../img/ico/plus-button.png ); +} + +#content #designer .actions #unload +{ + margin-right: 20px; +} + +#content #designer .actions #unload span +{ + background-image: url( ../../img/ico/cross.png ); +} + +#content #designer .actions #reload span +{ + background-image: url( ../../img/ico/arrow-circle.png ); +} + +#content #designer .actions #rename span +{ + background-image: url( ../../img/ico/ui-text-field-select.png ); +} + +#content #designer .actions #swap span +{ + background-image: url( ../../img/ico/arrow-switch.png ); +} + +#content #designer .actions div.action +{ + z-index: 100; + background-color: #fff; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 0px; + top: 36px; + padding: 10px; + width: 320px; +} + +/* Sample Documents */ + +#content #designer #analyze-buttons{ + float: right; + margin-right: 12px; +} + +#content #designer #query-buttons{ + margin-top: 20px; + float: right; + margin-right: 8px; +} + +#content #designer #queryButton span +{ + background-image: url( ../../img/ico/magnifier.png ); +} + +#content #designer #analyze span +{ + background-image: url( ../../img/ico/gear.png ); +} + +#content #designer #document-container +{ + padding: 5px; +} + +#content #designer #file-upload +{ + margin-bottom: 20px; +} + +/* Section header bars */ + +#content #designer .bar-desc +{ + color: #4D4D4D; + font-weight: normal; + margin-left: 10px; + white-space: pre; +} + +#content #designer .bar-holder +{ + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + height: 35px; +} + +#content #designer .bar-holder .bar +{ + height: 100%; + position: relative; +} + +#content #designer .bar-holder div .val +{ + border-right: 1px solid #f00; + display: block; + padding-right: 5px; + position: absolute; + right: 0; + top: 35px; + white-space: nowrap; +} + +#content #designer .bar-holder .bar-max.bar +{ + background-color: #f0f0f0; +} + +#content #designer .bar-holder .bar-max.val +{ + border-color: #f0f0f0; + color: #8D8D8D; +} + +#content #designer .bar-holder .bar-total.bar +{ + background-color: #c0c0c0; +} + +#content #designer .bar-holder .bar-total.val +{ + border-color: #c0c0c0; + color: #4D4D4D; +} + +#content #designer .bar-holder .bar-used.bar +{ + background-color: #969696; +} + +#content #designer .bar-holder .bar-used.val +{ + border-color: #969696; + color: #969696; +} + +#content #designer .bar-holder.bar-lvl-2 .bar-max.val { padding-top: 25px; } +#content #designer .bar-holder.bar-lvl-2 .bar-total.val { padding-top: 5px; } +#content #designer .bar-holder.bar-lvl-2 { margin-bottom: 45px; } + +#content #designer .bar-holder.bar-lvl-3 .bar-max.val { padding-top: 45px; } +#content #designer .bar-holder.bar-lvl-3 .bar-total.val { padding-top: 25px; } +#content #designer .bar-holder.bar-lvl-3 .bar-used.val { padding-top: 5px; } +#content #designer .bar-holder.bar-lvl-3 { margin-bottom: 65px; } + +#content #designer .analyzer, +#content #designer .analyzer li, +#content #designer .analyzer ul, +#content #designer .analyzer ul li +{ +} + +#content #designer .analyzer p, +#content #designer .analyzer dl +{ + float: left; +} + +#content #designer .analyzer p +{ + margin-right: 5px; + text-align: left; + width: 100px; + white-space: pre; +} + +#content #designer .analyzer p a +{ + cursor: auto; +} + +#content #designer .analyzer p a.analysis +{ + cursor: pointer; + display: block; +} + +#content #designer .analyzer p a.analysis span +{ + background-image: url( ../../img/ico/question-white.png ); + background-position: 0 50%; + padding-left: 21px; +} + +#content #designer .analyzer p a.analysis:hover span +{ + background-image: url( ../../img/ico/question.png ); + color: #008; +} + +#content #designer .analyzer a +{ + cursor: pointer; +} + +#content #designer .file-link +{ + cursor: pointer; + color: #003eff; + text-decoration-line: underline; + text-decoration-color: #003eff; +} + +#content #designer .analyzer .toggle +{ + background-image: url( ../../img/ico/chevron-small-expand.png ); + background-position: 100% 50%; + cursor: pointer; + display: block; + padding-right: 21px; +} + +#content #designer .analyzer .open .toggle +{ + background-image: url( ../../img/ico/chevron-small.png ); +} + +#content #designer .analyzer li +{ + border-top: 1px solid #f0f0f0; + margin-top: 10px; + padding-top: 10px; + margin-left: 10px; +} + +#content #designer .analyzer ul +{ + clear: left; + margin-left: 25px; + padding-top: 5px; +} + +#content #designer .analyzer .open ul +{ + display: block; +} + +#content #designer .analyzer ul li +{ + border-top: 1px solid #f8f8f8; + margin-top: 5px; + padding-top: 5px; +} + +#content #designer .analyzer ul p +{ + color: #4D4D4D; + margin-right: 5px; + text-align: left; + width: 80px; +} + +#content #designer .analyzer ul dd +{ + margin-left: 10px; +} + +#content #designer .analyzer ul dd +{ + background-image: url( ../../img/ico/document-list.png ); + background-position: 0 50%; + color: #4D4D4D; + padding-left: 21px; +} + +#content #designer .analyzer ul dd.ico-0 +{ + background-image: url( ../../img/ico/slash.png ); +} + +#content #designer .analyzer ul dd.ico-1 +{ + background-image: url( ../../img/ico/tick.png ); +} + +#content #designer #field-top +{ + width: 100%; +} + +#content #designer #field-top-left +{ + float: left; + width: 240px; + padding: 7px; +} + +#content #designer #field-top-right +{ + display: contents; +} + +#content #designer #tree-node-content form button.submit +{ + margin-left: 140px; +} + +#content #designer #tree-node-content form button.submit span +{ + background-image: url( ../../img/ico/tick.png ); +} + +#content #designer #field-bottom +{ + float: left; + width: 100%; +} + +#content #designer #schema-actions { + float: left; + width: 99%; +} + +#content #designer .schema-actions #addField { margin-right: 15px; } +#content #designer .schema-actions #addFieldType { margin-right: 15px; } + +#content #designer .schema-actions #addField span { background-image: url( ../../img/ico/document-list.png ); } +#content #designer .schema-actions #addCopyField span { background-image: url( ../../img/ico/document-import.png ); } +#content #designer .schema-actions #addFieldType span { background-image: url( ../../img/ico/document-text.png ); } + +#content #designer #updateSelected { float: right; margin-top:5px; } +#content #designer #updateSelected span { background-image: url( ../../img/ico/tick.png ); } +#content #designer #deleteSelected { margin-right: 0px; } +#content #designer #deleteSelected span { background-image: url( ../../img/ico/cross-button.png ); } + +#content #designer #updateStatusMessage { color: darkgreen; float: right; margin-top: 5px; background-image: url( ../../img/ico/tick.png ); } +#content #designer #updateStatusMessage span { margin-left: 18px; } +#content #designer .working { font-style: italic; color: black !important; float: right; margin-top: 5px; background-image: url( ../../img/loader.gif ) !important; } + +#content #designer .schema-actions div.action +{ + z-index: 100; + background-color: #fff; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 448px; + top: 31px; + padding: 10px; + width: 350px; +} + +#content #designer .schema-actions div.copyfield +{ + z-index: 100; + background-color: #fff; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 700px; + top: 31px; + padding: 10px; + width: 350px; +} + + +#content #designer .schema-actions p +{ + padding-bottom: 8px; +} + +#content #designer .schema-actions label +{ + margin-right: 6px; + float: left; + padding-top: 3px; + padding-bottom: 3px; + text-align: right; + width: 25%; +} + +#content #designer .schema-actions input, +#content #designer .schema-actions select, +#content #designer .schema-actions .buttons, +#content #designer .schema-actions .note span +{ + float: right; + width: 71%; +} + +#content #designer #add-errors +{ + float: left; + margin-top:10px; + margin-bottom: 10px; + min-height: 30px; +} + +#content #designer #add-errors .error +{ + background-image: url( ../../img/ico/cross-button.png ); + background-position: 10px 1px; + color: #c00; + font-weight: bold; +} + +#content #designer #add-errors .error span +{ + margin-left: 30px; +} + +#content #designer .schema-actions .chosen-container +{ + width: 71% !important; +} + +#content #designer .chosen-container { + width: 100%; +} +#content #designer .chosen-drop input, +#content #designer .chosen-results { + width: 100% !important; +} + +#content #designer .schema-actions label.checkbox { + margin-left: 27%; + text-align: left; + width: 73%; + padding: 0px; + margin-top: 0px; +} +#content #designer .schema-actions .checkbox input { + float: none; + width: auto; +} + +#content #designer .add_showhide { + background-image: url( ../../img/ico/chevron-small-expand.png ); + background-position: 100% 50%; + cursor: pointer; + padding-right: 21px; +} + +#content #designer .add_showhide.open { + background-image: url( ../../img/ico/chevron-small.png ); +} + +#content #designer #schema-actions button span +{ + background-image: url( ../../img/ico/cross.png ); +} +#content #designer #schema-actions button.submit span +{ + background-image: url( ../../img/ico/tick.png ); +} + +#content #designer #field-analysis +{ + margin-bottom: 0; + overflow: auto; + max-height: 135px; +} + +#content #designer #analysis #field-analysis-holder +{ + width: 100%; + padding: 5px; + max-height: 480px; + overflow: auto; +} + +#content #designer #analysis #field-analysis-holder #field-analysis-form +{ + width: 100%; + padding: 5px; +} + +#content #designer #analysis .settings +{ + clear: both; + padding: 5px; +} + +#content #designer #analysis select +{ + width: 200px; +} + +#content #designer #analysis .settings select.loader +{ + background-position: 3px 50%; + padding-left: 21px; +} + +#content #designer #analysis .settings select optgroup +{ + font-style: normal; + padding: 5px; +} + +#content #designer #analysis .settings select option +{ + padding-left: 10px; +} + +#content #designer #analysis .settings label +{ + display: block; + width: 150px; +} + +#content #designer #analysis .settings textarea +{ + display: block; +} + +#content #designer #analysis .settings +{ + float: left; + margin-right: 0.5%; +} + +#content #designer #analysis .analysis-error +{ + background-color: #f00; + background-image: url( ../../img/ico/construction.png ); + background-position: 10px 50%; + color: #fff; + font-weight: bold; + margin-bottom: 20px; + padding: 10px; + padding-left: 35px; +} + +#content #designer #analysis .analysis-error .head a +{ + color: #fff; + cursor: auto; +} + +#content #designer #analysis #analysis-result +{ + width: 100%; + float: left; + overflow: auto; +} + +#content #designer #analysis #analysis-result .index +{ + background-color: #fff; + padding-top: 20px; +} + +#content #designer #analysis #analysis-result table +{ + border-collapse: collapse; +} + +#content #designer #analysis #analysis-result td +{ + vertical-align: top; + white-space: nowrap; +} + +#content #designer #analysis #analysis-result td.part.analyzer div, +#content #designer #analysis #analysis-result td.part.spacer .holder, +#content #designer #analysis #analysis-result td td td +{ + padding-top: 1px; + padding-bottom: 1px; +} + +#content #designer #analysis #analysis-result.verbose_output td.legend +{ + display: table-cell; +} + +#content #designer #analysis #analysis-result.verbose_output td.data tr.verbose_output +{ + display: table-row; +} + +#content #designer #analysis #analysis-result .match +{ + background-color: #F0D9C3; +} + +#content #designer #analysis #analysis-result td.part +{ + padding-bottom: 10px; +} + +#content #designer #analysis #analysis-result td.part.analyzer div +{ + border-right: 1px solid #f0f0f0; + padding-right: 10px; +} + +#content #designer #analysis #analysis-result td.part.analyzer abbr +{ + color: #4D4D4D; +} + +#content #designer #analysis #analysis-result td.part.legend .holder, +#content #designer #analysis #analysis-result td.part.data .holder +{ + padding-left: 10px; + padding-right: 10px; + border-right: 1px solid #c0c0c0; +} + +#content #designer #analysis #analysis-result td.part.legend td +{ + color: #4D4D4D; +} + +#content #designer #analysis #analysis-result td.part.legend .holder +{ + border-right-color: #f0f0f0; +} + +#content #designer #analysis #analysis-result td.part.data:last-child .holder +{ + padding-right: 0; + border-right: 0; +} + +#content #designer #analysis #analysis-result td.details +{ + padding-left: 10px; + padding-right: 10px; + border-left: 1px solid #f0f0f0; + border-right: 1px solid #f0f0f0; +} + +#content #designer #analysis #analysis-result td.details:first-child +{ + padding-left: 0; + border-left: 0; +} + +#content #designer #analysis #analysis-result td.details:last-child +{ + padding-right: 0; + border-right: 0; +} + +#content #designer #analysis #analysis-result td.details tr.empty td +{ + color: #f0f0f0; +} + +#content #designer #analysis #analysis-result td.details tr.raw_bytes td +{ + letter-spacing: -1px; +} + +#content #designer #analysis #analysis-result .part table table td +{ + border-top: 1px solid #f0f0f0; +} + +#content #designer #analysis #analysis-result .part table table tr:first-child td +{ + border-top: 0; +} + +#content #designer #analysis #field-analysis h2 { background-image: url( ../../img/ico/receipt.png ); } +#content #designer #analysis .analysis-result h2 { background-image: url( ../../img/ico/receipt-invoice.png ); } + +#content #designer #schema-root-details +{ + min-height: 360px; + padding: 7px; +} + +#content #designer #schema-root-details #unique_key +{ + width: 150px; +} + +#content #designer #schema-root-details .note span +{ + float: right; + padding-left: 18px; +} + +#content #designer #schema-root-details .error +{ + background-image: url( ../../img/ico/cross-button.png ); + background-position: 0px 2px; + color: #c00; + font-weight: bold; +} + +/* diff dialog */ +#content #designer div.diff +{ + z-index: 100; + position: absolute; + background-color: #fff; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + top: 31px; + left: 650px; + padding: 10px; + width: 600px; + overflow: auto; + min-height: 370px; + max-height: 600px; +} + +#content #designer table.diff { + font-family: arial, sans-serif; + border-collapse: collapse; + width: 100%; + display: inline-block; + overflow: auto; +} + +#content #designer table.diff th { + font-family: arial, sans-serif; + font-weight: bold; + min-width: 100px; +} + +#content #designer p.diff-text { + margin-top: 15px; + margin-bottom: 5px; + font-size: medium; + font-weight: bold; +} + +#content #designer p.diff-field-name { + margin-top: 5px; + margin-bottom: 15px; + font-size: small; + font-weight: bold; +} + +#content #designer li.element +{ + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + margin-top: 5px; + margin-bottom: 15px; +} + +#content #designer .actions .diff-buttons { + margin-right: 15px; + float: right; + width: 48%; +} + +#content #designer p.old-value { + color: indianred; + text-decoration: line-through; +} + +#content #designer p.rem-value { + color: indianred; +} + +#content #designer p.new-value { + color: green; +} + +/* publish dialog */ +#content #designer .actions div.publish +{ + z-index: 100; + position: absolute; + background-color: #fff; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + top: 31px; + left: 1150px; + padding: 10px; + width: 380px; + height: 430px; +} + +#content #designer .actions .publish-button { + margin-right: 15px; +} + +#content #designer .actions .publish-button span +{ + background-image: url( ../../img/ico/disk-black.png ); +} + +#content #designer .actions .diff-button { + margin-right: 15px; +} + +#content #designer .actions .diff-button span { + background-image: url( ../../img/ico/document-convert.png ); +} + +#content #designer .actions button.reset span +{ + background-image: url( ../../img/ico/cross.png ); +} + +#content #designer #publish-dialog-note { + margin-bottom: 15px; +} + +#content #designer #publish-new-coll { + margin-top: 15px; + margin-bottom: 10px; +} + +#content #designer .publish-buttons +{ + margin-top: 20px; + float: right; + width: 48%; +} + +#content #designer #publish-affected { + overflow: auto; + height: 60px; +} + +#content #designer #reload-form { + height: 20px; +} + +#content #designer #file-node-text { + display:block; +} + +#content #designer #file-node { + padding: 7px; +} + +#content #designer #save-file span { + background-image: url( ../../img/ico/disk-black.png ); +} + +#content #designer #results-tree-left { + float: left; + width: 330px; + overflow: auto; + height: 350px; +} + +#content #designer #results-tree-right { + max-width: 800px; + float: left; + overflow: auto; + height: 350px; +} + +#content #designer #save-file-buttons { + margin-top: 15px; + margin-right: 5px; + display: block; + float: right; +} + +#content #designer #copy_dest { + width: 300px; +} + +#content #designer .hit-field { + padding: 3px; + width: 120px; +} + +#content #designer .hit-value { + padding: 3px; + word-wrap: break-word; + max-width: 700px; +} + +#content #designer #leaf-node .error +{ + background-image: url( ../../img/ico/cross-button.png ); + background-position: 0px 2px; + color: #c00; + font-weight: bold; +} + +#content #designer #leaf-node .error span +{ + padding-left: 18px; +} + +#content #designer #sample-docs .note +{ + background-image: url( ../../img/ico/information.png ); + background-position: 0px 2px; + color: #008; + font-weight: bold; +} + +#content #designer #confirm-dialog +{ + width: 350px; + height: 250px; +} + +#content #designer #confirm-dialog .warn span +{ + padding-left: 18px; +} + +#content #designer #confirm-dialog .warn +{ + background-image: url( ../../img/ico/exclamation-button.png ); + background-position: 0px 2px; + font-weight: bold; +} + +#content #designer #confirm-dialog #confirm-edit span { + background-image: url( ../../img/ico/tick.png ); +} + +#content #designer #confirm-dialog #confirm-colls { + margin-top: 15px; + margin-bottom: 15px; +} + + +#content #designer #sample-docs .note span +{ + padding-left: 18px; +} + +#content #designer .information +{ + display: block; + height: 40px; +} + +#content #designer #field-bottom fieldset.common +{ + margin-top: 10px; +} + +#content #designer #field-bottom fieldset legend, +#content #designer #field-bottom .optional.expanded legend +{ + display: block; + margin-left: 10px; + padding: 0px 5px; +} + +#content #designer #field-bottom fieldset legend label +{ + margin-top: 0; +} + +#content #designer #query-form select +{ + width: 150px; +} + +#content #designer #selected-hit { + padding: 5px; +} + +#content #designer tr.odd +{ + background-color: #f8f8f8; +} + +#content #designer .help +{ + font-weight: normal !important; + position: relative; +} + +#content #designer .help div.help +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 0px; + top: 0px; + padding: 6px; + width: 340px; +} + +#content #designer .help div.help-wide +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: -90px; + top: 0px; + padding: 6px; + width: 420px; +} + +#content #designer .help div.help-wider +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 0px; + top: 0px; + padding: 6px; + width: 430px; +} + +#content #designer .help div.help-top +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 0px; + top: -200px; + padding: 6px; + width: 420px; +} + +#content #designer .help-anchor +{ + margin-top: 7px; + margin-left: 18px; + margin-bottom: 10px; +} + +#content #designer .help-anchor a +{ + color: #003eff; + text-decoration-line: underline; + text-decoration-color: #003eff; +} + +#content #designer .help-ico { + margin-left: 3px; + margin-top: 3px; +} + +#content #designer #analysis .verbose_output +{ + padding: 3px; + float: left; + margin-left: 260px; +} + +#content #designer #analysis .verbose_output a +{ + background-image: url( ../../img/ico/ui-check-box-uncheck.png ); + background-position: 0 50%; + color: #4D4D4D; + display: block; + padding-left: 21px; +} + +#content #designer #analysis .verbose_output.active a +{ + background-image: url( ../../img/ico/ui-check-box.png ); +} + +#content #designer #file-node .error +{ + background-image: url( ../../img/ico/cross-button.png ); + color: #c00; + font-weight: bold; +} + +#content #designer #file-node .error span +{ + margin-left: 20px; +} + +#content #designer .field-top-form { + margin-bottom: 7px; + width: 300px; +} + +#content #designer .field-top-form label { + text-align: right; + margin-right: 5px; + width: 150px; +} + +#content #designer .field-top-form select +{ + display: block; + width: 150px; +} + +#content #designer .warn-dialog +{ + z-index: 200; + background-color: #f0f0f0; + border: 1px solid #a0a0a0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 350px; + top: 95px; + padding: 20px; + width: 450px; +} + +#content #designer #warn-dialog #warn-dialog-buttons { + float: right; +} + +#content #designer #warn-dialog .warn-button { + margin-right: 15px; +} + +#content #designer #warn-dialog .warn-button span +{ + background-image: url( ../../img/ico/tick.png ); +} + +#content #designer .error-dialog +{ + z-index: 200; + background-color: #f0f0f0; + border: 1px solid #c00; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 350px; + top: 95px; + padding: 20px; + width: 450px; +} + +#content #designer #error-dialog #error-dialog-buttons { + float: right; +} + +#content #designer #error-dialog .error-button { + margin-right: 15px; +} + +#content #designer #error-dialog .error-button span +{ + background-image: url( ../../img/ico/tick.png ); +} + +#content #designer #error-dialog .reload-error-button { + margin-right: 15px; +} + +#content #designer #error-dialog .reload-error-button span +{ + background-image: url( ../../img/ico/arrow-circle.png ); +} + +#content #designer #error-dialog-note { + color: #c00; + font-weight: bold; + margin-bottom: 15px; +} + +#content #designer #error-dialog-details { + min-height: 80px; + margin-bottom: 15px; +} + +#content #designer #edit-analysis-json-link { + margin-top: 10px; + float: right; +} + +#content #designer #edit-analysis-json-link a { + cursor: pointer; + color: #003eff; + text-decoration-line: underline; + text-decoration-color: #003eff; +} + +#content #designer #tree-filters { + font-size: 11px; + max-width: 400px; + overflow: hidden; + margin-top: 2px; + margin-bottom: 6px; +} + +#content #designer #tree-filters-cat { + max-width: 70px; + font-size: 11px; +} + +#content #designer #tree-filters-options { + max-width: 90px; + font-size: 11px; +} + +#content #designer #copy_schema { + width: 200px; +} + +#content #designer #currentSchemaLabel { + font-weight: bold; + margin-top: 2px; +} + +#content #designer #treeFilterFeatureEnabledSpan { + display: inline; + font-size: 11px; +} + +#content #designer #treeFilterFeatureEnabledSpan input { + padding: 0px; + margin-top: 4px; +} + +#content #designer .container-node { + max-height: 540px; + overflow: auto; +} + + +#content #designer .prop { + border-bottom: 1px solid #dddddd; + padding: 3px; + text-align: left; + min-width: 80px; + word-wrap: break-word; + max-width: 140px; +} + +#content #designer .prop-flag { + border-bottom: 1px solid #dddddd; + padding: 3px; + text-align: center; +} + +#content #designer .prop-hdr { + border-bottom: 1px solid #dddddd; + padding: 3px; + font-weight: bold; + text-align: left; + min-width: 80px; + word-wrap: break-word; + max-width: 140px; +} + +#content #designer .prop-hdr-flag { + border-bottom: 1px solid #dddddd; + padding: 3px; + font-weight: bold; + text-align: center; + min-width: 65px; +} + +#content #designer #editDocumentsToolbar { float: right; margin-top:0px; margin-left:20px; } +#content #designer #editDocuments span { background-image: url( ../../img/ico/pencil.png ); } + +#content #designer .help div.help-small +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: -120px; + top: 0px; + padding: 6px; + width: 250px; +} + + diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/security.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/security.css new file mode 100755 index 0000000000..61ce0814d7 --- /dev/null +++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/security.css @@ -0,0 +1,700 @@ +/* + +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. + +*/ +#securityPanel +{ + position: relative; +} + +#securityPanel .main-col +{ + float: left; + padding: 7px; + min-width: 700px; +} + +#securityPanel #users h2 { background-image: url( ../../img/ico/users.png ); } +#securityPanel #roles h2 { background-image: url( ../../img/ico/key.png ); } +#securityPanel #permissions h2 { background-image: url( ../../img/ico/lock.png ); } +#securityPanel #authn h2 { background-image: url( ../../img/ico/shield.png ); } + +#securityPanel .ref-guide-link +{ + cursor: pointer; + color: #003eff; + text-decoration-line: underline; + text-decoration-color: #003eff; +} + +#securityPanel .warning-msg +{ + display: block; + font-weight: bold; + margin-bottom: 15px; +} + +#securityPanel .external-msg +{ + display: block; + margin-bottom: 20px; + margin-top: 20px; + margin-left: 30px; +} + +#securityPanel .error-msg +{ + display: block; + font-weight: bold; + color: #c00; + margin-bottom: 15px; +} + +#securityPanel .table-hdr { + border-bottom: 1px solid #dddddd; + padding: 3px; + font-weight: bold; + text-align: left; + word-wrap: break-word; +} + +#securityPanel .td-name { + width: 150px; +} + +#securityPanel .td-role { + width: 100px; +} + +#securityPanel .td-roles { + width: 200px; +} + +#securityPanel .td-coll { + width: 120px; +} + +#securityPanel .td-path { + width: 250px; +} + +#securityPanel .td-method { + width: 100px; +} + +#securityPanel .td-params { + width: 200px; +} + +#securityPanel .table-data { + border-bottom: 1px solid #dddddd; + padding: 3px; + text-align: left; + word-wrap: break-word; + max-width: 450px; +} + +#securityPanel .table-warn { + padding: 3px; + text-align: left; + word-wrap: break-word; + max-width: 90%; +} + +#securityPanel tr.odd +{ + background-color: #f8f8f8; +} + +#securityPanel #authn +{ + display: block; +} + +#securityPanel #user-actions +{ + margin-right: 5px; + float: right; +} + +#securityPanel #perm-actions +{ + margin-right: 5px; + float: right; +} + +#securityPanel #authn form .buttons +{ + margin-top: 10px; + float: right; + width: 71%; +} + +#securityPanel #authn form button.submit +{ + margin-right: 20px; +} + +#securityPanel #authn form button.submit span +{ + background-image: url( ../../img/ico/tick.png ); +} + +#securityPanel #authn form button.reset span +{ + background-image: url( ../../img/ico/cross.png ); +} + +#securityPanel #authn #user-dialog +{ + z-index: 100; + background-color: #fff; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + padding: 10px; + width: 350px; +} + +#securityPanel #authn #role-dialog +{ + z-index: 100; + background-color: #fff; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + padding: 10px; + width: 350px; +} + +#securityPanel #authn #add-permission-dialog +{ + z-index: 100; + background-color: #fff; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + top: 190px; + padding: 10px; + width: 530px; +} + +#securityPanel #authn #add-permission-dialog form label +{ + float: left; + padding-top: 3px; + padding-bottom: 3px; + text-align: right; + width: 110px; + margin-right: 6px; +} + +#securityPanel #authn #user-dialog form label +{ + float: left; + padding-top: 3px; + padding-bottom: 3px; + text-align: right; + width: 37%; + margin-right: 6px; +} + +#securityPanel #authn form p { + padding-bottom: 8px; +} + +#securityPanel #add-user span +{ + background-image: url( ../../img/ico/useradd.png ); +} + +#securityPanel #add-permission +{ + margin-left: 10px; +} + +#securityPanel #add-permission span +{ + background-image: url( ../../img/ico/lockplus.png ); +} + +#securityPanel #authn .validate-error +{ + background-image: url( ../../img/ico/cross.png ); +} + +#securityPanel #authn .validate-error span +{ + color: #c00; + font-weight: bold; + margin-left: 18px; +} + +#securityPanel #authn .formMessageHolder { + display: block; + margin-top: 7px; + height: 56px; + margin-bottom: 7px; + margin-left: 10px; +} + +#securityPanel .form-field { + margin-top: 7px; +} + +#securityPanel #authn .input-text { + width: 142px; +} + +#securityPanel #authn .input-check { + margin-left: 0px; + text-align: left; + width: 25px; +} + +#securityPanel #authn #add_perm_path { + width: 280px; +} + +#securityPanel #authn #add_perm_params { + width: 300px; +} + +#securityPanel #authn #add_user_roles { + width: 148px; +} + +#securityPanel #authn #add_perm_roles { + width: 148px; +} + +#securityPanel #authn #predefined { + width: 172px; +} + +#securityPanel #users-content +{ + height: 230px; + margin-bottom: 20px; +} + +#securityPanel #users-table +{ + height: 200px; + overflow: auto; +} + +#securityPanel #roles-content +{ + height: 230px; + margin-bottom: 20px; +} + +#securityPanel #roles-table +{ + height: 200px; + overflow: auto; +} + +#securityPanel #perms-table +{ + max-height: 400px; + overflow: auto; +} + +#securityPanel .help div.help-perm +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 20px; + top: 90px; + padding: 6px; + width: 420px; +} + +#securityPanel .help-anchor +{ + margin-top: 7px; + margin-left: 18px; + margin-bottom: 10px; +} + +#securityPanel .help-anchor a +{ + color: #003eff; + text-decoration-line: underline; + text-decoration-color: #003eff; +} + +#securityPanel .help-ico { + margin-left: 3px; + margin-top: 3px; +} + +#securityPanel .heading { + display: block; + font-weight: bold; + font-size: 12px; + margin-left: 10px; + margin-bottom: 10px; +} + +#securityPanel .users-left +{ + float: left; + width: 45%; + margin-right: 20px; +} + +#securityPanel .roles-right +{ + overflow: auto; +} + +#securityPanel #user-filters +{ + margin-top: 3px; + margin-bottom: 10px; +} + +#securityPanel #user-filter-type +{ + margin-right: 5px; +} + +#securityPanel #user-filter-text +{ + width: 100px; +} + +#securityPanel #perm-filters +{ + margin-top: 3px; + margin-bottom: 10px; +} + +#securityPanel #perm-filter-type +{ + margin-right: 5px; +} + +#securityPanel #perm-filter-text +{ + width: 100px; +} + +#securityPanel #delete-user +{ + margin-left: 15px; + float: right; +} + +#securityPanel #delete-user span +{ + background-image: url( ../../img/ico/cross-button.png ); +} + +#securityPanel #user-heading { + display: block; + padding: 4px; + margin-bottom: 22px; +} + +#securityPanel #role-heading { + display: block; + padding: 4px; + margin-bottom: 22px; +} + +#securityPanel #perm-heading { + display: block; + padding: 4px; + margin-bottom: 22px; +} + +#securityPanel #delete-perm +{ + margin-left: 15px; + float: right; +} + +#securityPanel #delete-perm span +{ + background-image: url( ../../img/ico/cross-button.png ); +} + +#securityPanel #role-filters +{ + margin-top: 3px; + margin-bottom: 10px; +} + +#securityPanel #role-filter-type +{ + margin-right: 5px; +} + +#securityPanel #role-filter-text +{ + width: 100px; +} + +#securityPanel #role-actions +{ + margin-right: 5px; + float: right; +} + +#securityPanel #add-role span +{ + background-image: url( ../../img/ico/keyplus.png ); +} + +#securityPanel #authn-settings { + margin-top: 5px; + margin-bottom: 20px; +} + +#securityPanel #plugins { + display: block; + margin-bottom: 10px; +} + +#securityPanel #authzPlugin { + margin-left: 40px; +} + +#securityPanel #realm-field { + display: inline; + width: 150px; + margin-right: 30px; +} + +#securityPanel #block-field { + display: inline; + width: 220px; + margin-right: 30px; +} + +#securityPanel #forward-field { + display: inline; + width: 220px; +} + +#securityPanel #blockUnknownHelp +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 210px; + top: 100px; + padding: 6px; + width: 380px; +} + +#securityPanel #multiAuthBasicHelp +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 210px; + top: 70px; + padding: 6px; + width: 380px; +} + +#securityPanel #forwardCredsHelp +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 450px; + top: 100px; + padding: 6px; + width: 380px; +} + +#securityPanel #authn-content +{ + margin-top: 10px; + height: 80px; + overflow: auto; +} + +#securityPanel #authn #role-dialog form label +{ + float: left; + padding-top: 3px; + padding-bottom: 3px; + text-align: right; + width: 37%; + margin-right: 6px; +} + +#securityPanel #add_perm_custom +{ + margin-left: 5px; + display: inline; +} + +#securityPanel #add_perm_name { + width: 125px; +} + +#securityPanel #perm-select { + margin-top: 12px; + margin-bottom: 15px; +} + +#securityPanel .help div.help-index +{ + z-index: 200; + background-color: #FCF0AD; + border: 1px solid #f0f0f0; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 20px; + top: 90px; + padding: 6px; + width: 380px; +} + +#securityPanel #param-rows +{ + display: block; + height: 100px; + max-height: 100px; + overflow: auto; +} + +#securityPanel .row +{ + display: block; + margin-bottom: 5px; + margin-right: 100px; +} + +#securityPanel .row .param-name +{ + display: inline; + float: left; + width: 90px; +} + +#securityPanel .row .param-value +{ + display: inline; + width: 140px; +} + +#securityPanel .row .param-buttons +{ + float: right; + width: 40px; +} + +#securityPanel .row a +{ + background-position: 50% 50%; + display: block; + height: 25px; + width: 49%; +} + +#securityPanel .row a.add +{ + background-image: url( ../../img/ico/plus-button.png ); + float: right; +} + +#securityPanel .row a.rem +{ + background-image: url( ../../img/ico/minus-button.png ); + float: left; +} + +#securityPanel .error-dialog +{ + z-index: 200; + background-color: #f0f0f0; + border: 1px solid #c00; + box-shadow: 5px 5px 10px #c0c0c0; + -moz-box-shadow: 5px 5px 10px #c0c0c0; + -webkit-box-shadow: 5px 5px 10px #c0c0c0; + position: absolute; + left: 350px; + top: 95px; + padding: 20px; + width: 450px; +} + +#securityPanel #error-dialog #error-dialog-buttons { + float: right; +} + +#securityPanel #error-dialog .error-button { + margin-right: 15px; +} + +#securityPanel #error-dialog .error-button span +{ + background-image: url( ../../img/ico/tick.png ); +} + +#securityPanel #error-dialog-note { + color: #c00; + font-weight: bold; + margin-bottom: 15px; +} + +#securityPanel #error-dialog-details { + min-height: 80px; + margin-bottom: 15px; +} + +#securityPanel #authnPlugin { + margin-left: 20px; +} + +#securityPanel .editable { + cursor: pointer; +} diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/key.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/key.png new file mode 100755 index 0000000000..82846369f3 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/key.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/keyplus.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/keyplus.png new file mode 100755 index 0000000000..9c3e361d75 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/keyplus.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/lock.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/lock.png new file mode 100755 index 0000000000..571c16d386 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/lock.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/lockplus.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/lockplus.png new file mode 100755 index 0000000000..e3aa6e34ca Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/lockplus.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/logout.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/logout.png new file mode 100755 index 0000000000..2bc51acc2a Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/logout.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-slave.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-follower.png similarity index 100% rename from KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-slave.png rename to KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-follower.png diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-master.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-leader.png similarity index 100% rename from KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-master.png rename to KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-leader.png diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/shield--exclamation.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/shield--exclamation.png new file mode 100755 index 0000000000..37c57b9f9e Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/shield--exclamation.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/shield.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/shield.png new file mode 100755 index 0000000000..c41e5abe63 Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/shield.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/useradd.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/useradd.png new file mode 100755 index 0000000000..9f6c0f5ffc Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/useradd.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/32px.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/32px.png index 4357b91028..ca6af20677 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/32px.png and b/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/32px.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/40px.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/40px.png index d0255223f4..2a3fcb9dfa 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/40px.png and b/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/40px.png differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/throbber.gif b/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/throbber.gif index 64c8eebb87..cf06c1ad0f 100755 Binary files a/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/throbber.gif and b/KeywordSearch/solr/server/solr-webapp/webapp/img/jstree/throbber.gif differ diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/index.html b/KeywordSearch/solr/server/solr-webapp/webapp/index.html index 0e7c3ba0d7..b22eda124e 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/index.html +++ b/KeywordSearch/solr/server/solr-webapp/webapp/index.html @@ -26,6 +26,8 @@ limitations under the License. + + @@ -53,44 +55,46 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -106,7 +110,7 @@ limitations under the License.
-
+

SolrCore Initialization Failures

    @@ -131,7 +135,7 @@ limitations under the License.

    Continuing to load data...

-
+
{{exception.msg}}
@@ -148,16 +152,18 @@ limitations under the License.
  • {{ environment_label }}
  • {{http401 ? "Login" : "Logout " + currentUser}}

  • - +
  • Dashboard

  • - +
  • Logging

  • - + +
  • Security

  • +
  • Cloud

    • Nodes
    • @@ -166,12 +172,14 @@ limitations under the License.
    • Graph
  • - + +
  • Schema Designer

  • +
  • Collections

  • Core Admin

  • - +
  • Java Properties

  • - +
  • Thread Dump

  • Suggestions

  • diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/app.js b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/app.js index c2b4cbcd6b..46851a7af2 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/app.js +++ b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/app.js @@ -188,6 +188,14 @@ solrAdminApp.config([ templateUrl: 'partials/segments.html', controller: 'SegmentsController' }). + when('/~schema-designer', { + templateUrl: 'partials/schema-designer.html', + controller: 'SchemaDesignerController' + }). + when('/~security', { + templateUrl: 'partials/security.html', + controller: 'SecurityController' + }). otherwise({ templateUrl: 'partials/unknown.html', controller: 'UnknownController' @@ -335,12 +343,17 @@ solrAdminApp.config([ var treeConfig = { 'core' : { 'animation' : 0, - 'data': scope.data, 'worker': false } }; var tree = $(element).jstree(treeConfig); + + // This is done to ensure that the data can be refreshed if it is updated behind the scenes. + // Putting the data in the treeConfig makes it stack and doesn't update. + $(element).jstree(true).settings.core.data = scope.data; + $(element).jstree(true).refresh(); + $(element).jstree('open_node','li:first'); if (tree) { element.bind("select_node.jstree", function (event, data) { @@ -378,7 +391,9 @@ solrAdminApp.config([ if (sessionStorage.getItem("auth.header")) { config.headers['Authorization'] = sessionStorage.getItem("auth.header"); } - config.timeout = 10000; + if (!config.timeout) { + config.timeout = 10000; + } return config || $q.when(config); }; @@ -411,6 +426,12 @@ solrAdminApp.config([ if (rejection.config.headers.doNotIntercept) { return rejection; } + + // Some page controllers, such as Schema Designer, handle errors internally to provide a better user experience than the global error handler + var isHandledByPageController = + (rejection.config.url && rejection.config.url.startsWith("/api/schema-designer/")) || + (rejection.status === 403 && $location.path() === "/~security"); + if (rejection.status === 0) { $rootScope.$broadcast('connectionStatusActive'); if (!$rootScope.retryCount) $rootScope.retryCount=0; @@ -418,7 +439,7 @@ solrAdminApp.config([ var $http = $injector.get('$http'); var result = $http(rejection.config); return result; - } else if (rejection.status === 401) { + } else if (rejection.status === 401 && !isHandledByPageController) { // Authentication redirect var headers = rejection.headers(); var wwwAuthHeader = headers['www-authenticate']; @@ -440,7 +461,14 @@ solrAdminApp.config([ $location.path('/login'); } } else { - $rootScope.exceptions[rejection.config.url] = rejection.data.error; + // some controllers prefer to handle errors internally + if (!isHandledByPageController) { + if (rejection.data.error) { + $rootScope.exceptions[rejection.config.url] = rejection.data.error; + } else if (rejection.data.message) { + $rootScope.exceptions[rejection.config.url] = {msg:rejection.data.message+" from "+rejection.data.url}; + } + } } return $q.reject(rejection); }; @@ -468,7 +496,7 @@ solrAdminApp.config([ }; }); -solrAdminApp.controller('MainController', function($scope, $route, $rootScope, $location, Cores, Collections, System, Ping, Constants) { +solrAdminApp.controller('MainController', function($scope, $route, $rootScope, $location, Cores, Collections, System, Ping, Constants, SchemaDesigner) { $rootScope.exceptions={}; @@ -490,6 +518,9 @@ solrAdminApp.controller('MainController', function($scope, $route, $rootScope, $ delete $scope.currentCore; for (key in data.status) { var core = data.status[key]; + if (core.name.startsWith("._designer_")) { + continue; + } $scope.cores.push(core); if ((!$scope.isSolrCloud || pageType == Constants.IS_CORE_PAGE) && core.name == currentCoreName) { $scope.currentCore = core; @@ -499,6 +530,7 @@ solrAdminApp.controller('MainController', function($scope, $route, $rootScope, $ $scope.initFailures = data.initFailures; }); + $scope.isSchemaDesignerEnabled = true; System.get(function(data) { $scope.isCloudEnabled = data.mode.match( /solrcloud/i ); @@ -521,6 +553,9 @@ solrAdminApp.controller('MainController', function($scope, $route, $rootScope, $ } $scope.collections = []; for (key in cdata.collections) { + if (cdata.collections[key].startsWith("._designer_")) { + continue; // ignore temp designer collections + } var collection = {name: cdata.collections[key], type: 'collection'}; $scope.collections.push(collection); if (pageType == Constants.IS_COLLECTION_PAGE && collection.name == currentCollectionName) { @@ -533,6 +568,14 @@ solrAdminApp.controller('MainController', function($scope, $route, $rootScope, $ $scope.aliases_and_collections = $scope.aliases_and_collections.concat({name:'-----'}); } $scope.aliases_and_collections = $scope.aliases_and_collections.concat($scope.collections); + + SchemaDesigner.get({path: "configs"}, function (ignore) { + // no-op, just checking if we have access to this path + }, function(e) { + if (e.status === 401 || e.status === 403) { + $scope.isSchemaDesignerEnabled = false; + } + }); }); }); } diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/cloud.js b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/cloud.js index 976c048c96..783de1e7ae 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/cloud.js +++ b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/cloud.js @@ -562,14 +562,12 @@ var treeSubController = function($scope, Zookeeper) { var path = decodeURIComponent(link.replace(/.*[\\?&]path=([^&#]*).*/, "$1")); Zookeeper.detail({path: path}, function(data) { $scope.znode = data.znode; - var path = data.znode.path.split( '.' ); - if(path.length >1) { - $scope.lang = path.pop(); + if (data.znode.path.endsWith("/managed-schema") || data.znode.path.endsWith(".xml.bak")) { + $scope.lang = "xml"; } else { var lastPathElement = data.znode.path.split( '/' ).pop(); - if (lastPathElement == "managed-schema") { - $scope.lang = "xml"; - } + var lastDotAt = lastPathElement ? lastPathElement.lastIndexOf('.') : -1; + $scope.lang = lastDotAt != -1 ? lastPathElement.substring(lastDotAt+1) : "txt"; } $scope.showData = true; }); diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/collections.js b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/collections.js index 480a8b2fa0..a2305c0ae2 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/collections.js +++ b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/collections.js @@ -26,6 +26,9 @@ solrAdminApp.controller('CollectionsController', Collections.status(function (data) { $scope.collections = []; for (var name in data.cluster.collections) { + if (name.startsWith("._designer_")) { + continue; + } var collection = data.cluster.collections[name]; collection.name = name; collection.type = 'collection'; @@ -216,7 +219,7 @@ solrAdminApp.controller('CollectionsController', $scope.nodes = []; var children = data.tree[0].children; for (var child in children) { - $scope.nodes.push(children[child].data.title); + $scope.nodes.push(children[child].text); } }); }; @@ -225,7 +228,7 @@ solrAdminApp.controller('CollectionsController', $scope.hideAll(); replica.showRemove = !replica.showRemove; }; - + $scope.toggleRemoveShard = function(shard) { $scope.hideAll(); shard.showRemove = !shard.showRemove; @@ -252,6 +255,7 @@ solrAdminApp.controller('CollectionsController', var params = { collection: shard.collection, shard: shard.name, + type: shard.replicaType } if (shard.replicaNodeName && shard.replicaNodeName != "") { params.node = shard.replicaNodeName; @@ -261,7 +265,7 @@ solrAdminApp.controller('CollectionsController', $timeout(function () { shard.replicaAdded = false; shard.showAdd = false; - $$scope.refresh(); + $scope.refresh(); }, 2000); }); }; diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/core-overview.js b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/core-overview.js index 8f86575669..90c3b9ce09 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/core-overview.js +++ b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/core-overview.js @@ -33,8 +33,8 @@ function($scope, $rootScope, $routeParams, Luke, CoreSystem, Update, Replication $scope.refreshReplication = function() { Replication.details({core: $routeParams.core}, function(data) { - $scope.isSlave = data.details.isSlave == "true"; - $scope.isMaster = data.details.isMaster == "true"; + $scope.isFollower = data.details.isSlave == "true"; + $scope.isLeader = data.details.isMaster == "true"; $scope.replication = data.details; }, function(error) { diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/files.js b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/files.js index 6155d3ea96..7a12fb2004 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/files.js +++ b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/files.js @@ -15,8 +15,8 @@ limitations under the License. */ -var contentTypeMap = { xml : 'text/xml', html : 'text/html', js : 'text/javascript', json : 'application/json', 'css' : 'text/css' }; -var languages = {js: "javascript", xml:"xml", xsl:"xml", vm: "xml", html: "xml", json: "json", css: "css"}; +var contentTypeMap = { xml : 'application/xml', html : 'application/xml', js : 'application/javascript', json : 'application/json', css : 'text/plain' }; +var languages = {js: "javascript", xml:"xml", xsl:"xml", vm: "xml", html: "xml", json: "json"}; solrAdminApp.controller('FilesController', function($scope, $rootScope, $routeParams, $location, Files, Constants) { @@ -31,9 +31,9 @@ solrAdminApp.controller('FilesController', var process = function (path, tree) { var params = {core: $routeParams.core}; - if (path.slice(-1) == '/') { + if (path.slice(-1) === '/') { params.file = path.slice(0, -1); - } else if (path!='') { + } else if (path!=='') { params.file = path; } @@ -48,10 +48,10 @@ solrAdminApp.controller('FilesController', if (filedata.directory) { file = file + "/"; - if ($scope.file && $scope.file.indexOf(path + file) == 0) { - state = "open"; + if ($scope.file && $scope.file.indexOf(path + file) === 0) { + state = {"opened": true}; } else { - state = "closed"; + state = {"opened": false}; } children = []; process(path + file, children); @@ -68,10 +68,10 @@ solrAdminApp.controller('FilesController', $scope.tree = []; process("", $scope.tree); - if ($scope.file && $scope.file != '' && $scope.file.split('').pop()!='/') { + if ($scope.file && $scope.file !== '' && $scope.file.split('').pop()!=='/') { var extension; - if ($scope.file == "managed-schema") { - extension = contentTypeMap['xml']; + if ($scope.file === "managed-schema") { + extension = 'xml'; } else { extension = $scope.file.match( /\.(\w+)$/)[1] || ''; } diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/query.js b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/query.js index eb8bf9847f..ad4e78305e 100755 --- a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/query.js +++ b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/query.js @@ -19,17 +19,80 @@ solrAdminApp.controller('QueryController', function($scope, $routeParams, $location, Query, Constants){ $scope.resetMenu("query", Constants.IS_COLLECTION_PAGE); - // @todo read URL parameters into scope - $scope.query = {q:'*:*'}; + $scope._models = []; $scope.filters = [{fq:""}]; - $scope.dismax = {defType: "dismax"}; - $scope.edismax = {defType: "edismax", stopwords: true, lowercaseOperators: false}; - $scope.hl = {hl:"on"}; - $scope.facet = {facet: "on"}; - $scope.spatial = {}; - $scope.spellcheck = {spellcheck:"on"}; - $scope.debugQuery = {debugQuery: "on"}; - $scope.qt = "/select"; + $scope.val = {}; + $scope.val['q'] = "*:*"; + $scope.val['q.op'] = "OR"; + $scope.val['defType'] = ""; + $scope.val['indent'] = true; + + // get list of ng-models that have a form element + function setModels(argTagName){ + var fields = document.getElementsByTagName(argTagName); + for( var i = 0, iLen = fields.length; i -1 ) { + // parameters stored in "val" will be used in both links (admin link and REST-request) + var index = $scope._models.map(function(field){return field.modelName}).indexOf("val['" + argKey + "']"); + var field = $scope._models[index].element; + if( argValue === "true" || argValue === "false"){ + // use real booleans + argValue = argValue === "true"; + } else if( field.tagName.toUpperCase() === "INPUT" && field.type === "checkbox" && (argValue === "on" || argValue === "off") ){ + argValue = argValue === "on"; + } + $scope.val[argKey] = argValue; + } else if( $scope._models.map(function(field){return field.modelName}).indexOf(argKey) > -1 ) { + // parameters that will only be used to generate the admin link + $scope[argKey] = argValue; + } else { + insertToRawParams(argKey, argValue); + } + } + // store not processed values to be displayed in a field + function insertToRawParams(argKey, argValue){ + if( $scope.rawParams == null ){ + $scope.rawParams = ""; + } else { + $scope.rawParams += "&"; + } + $scope.rawParams += argKey + "=" + argValue; + } + function addFilters(argObject){ + if( argObject ){ + $scope.filters = []; + if( Array.isArray(argObject) ){ + for( var i = 0, iLen = argObject.length; i 0) && key[0]!="$") { + if (typeof(terms) == typeof(true) || (terms.length && terms.length > 0 && key[0]!=="$") ) { set(key, terms); } } - }; + } + // remove non-visible fields from the request-params + var purgeParams = function(params, fields, bRemove){ + if( !bRemove ){ + return; + } + for( var i = 0, iLen = fields.length; i=0) { title = file.replace(':', ' » '); var parts = file.split(':'); - if (isSlave) { + if (isFollower) { short = parts[1]; } else { short = parts[0]; } } - master.files.push({title:title, name:short}); + leader.files.push({title:title, name:short}); } } - return master; + return leader; } diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/schema-designer.js b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/schema-designer.js new file mode 100755 index 0000000000..b49f083d42 --- /dev/null +++ b/KeywordSearch/solr/server/solr-webapp/webapp/js/angular/controllers/schema-designer.js @@ -0,0 +1,2025 @@ +/* + 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. +*/ + +solrAdminApp.controller('SchemaDesignerController', function ($scope, $timeout, $cookies, $window, Constants, SchemaDesigner, Luke) { + $scope.resetMenu("schema-designer", Constants.IS_ROOT_PAGE); + + $scope.schemas = []; + $scope.publishedSchemas = []; + $scope.sampleDocIds = []; + $scope.sortableFields = []; + $scope.hlFields = []; + $scope.types = []; + + $scope.onWarning = function (warnMsg, warnDetails) { + $scope.updateWorking = false; + delete $scope.updateStatusMessage; + $scope.apiWarning = warnMsg; + $scope.apiWarningDetails = warnDetails; + }; + + $scope.onError = function (errorMsg, errorCode, errorDetails) { + $scope.updateWorking = false; + delete $scope.updateStatusMessage; + $scope.designerAPIError = errorMsg; + if (errorDetails) { + var errorDetailsStr = ""; + if (errorDetails["error"]) { + errorDetailsStr = errorDetails["error"]; + } else { + for (var id in errorDetails) { + var msg = errorDetails[id]; + var at = msg.indexOf("ERROR: "); + if (at !== -1) { + msg = msg.substring(at+7); + } + if (!msg.includes(id)) { + msg = id+": "+msg; + } + errorDetailsStr += msg+"\n\n"; + } + } + $scope.designerAPIErrorDetails = errorDetailsStr; + } else { + delete $scope.designerAPIErrorDetails; + } + + if (errorCode === 409) { + $scope.schemaVersion = -1; // reset to get the latest + $scope.isVersionMismatch = true; + $scope.errorButton = "Reload Schema"; + } else if (errorCode < 500) { + $scope.isVersionMismatch = false; + $scope.errorButton = "OK"; + } // else 500 errors get the top-level error message + }; + + $scope.errorHandler = function (e) { + var error = e.data && e.data.error ? e.data.error : null; + if (error) { + $scope.onError(error.msg, error.code, e.data.errorDetails); + } else { + // when a timeout occurs, the error details are sparse so just give the user a hint that something was off + var path = e.config && e.config.url ? e.config.url : "/api/schema-designer"; + var reloadMsg = ""; + if (path.includes("/analyze")) { + reloadMsg = " Re-try analyzing your sample docs by clicking on 'Analyze Documents' again." + } + $scope.onError("Request to "+path+" failed!", 408, + {"error":"Most likely the request timed out; check server log for more details."+reloadMsg}); + } + }; + + $scope.closeWarnDialog = function () { + delete $scope.apiWarning; + delete $scope.apiWarningDetails; + }; + + $scope.closeErrorDialog = function () { + delete $scope.designerAPIError; + delete $scope.designerAPIErrorDetails; + if ($scope.isVersionMismatch) { + $scope.isVersionMismatch = false; + var nodeId = "/"; + if ($scope.selectedNode) { + nodeId = $scope.selectedNode.href; + } + $scope.doAnalyze(nodeId); + } + }; + + $scope.refresh = function () { + $scope.isSchemaDesignerEnabled = true; + + delete $scope.helpId; + + $scope.updateStatusMessage = ""; + $scope.analysisVerbose = false; + $scope.updateWorking = false; + $scope.currentSchema = ""; + + delete $scope.hasDocsOnServer; + delete $scope.queryResultsTree; + + $scope.languages = ["*"]; + $scope.copyFrom = "_default"; + delete $scope.sampleMessage; + delete $scope.sampleDocuments; + + $scope.schemaVersion = -1; + $scope.schemaTree = {}; + $scope.showSchemaActions = false; + $scope.sampleDocIds = []; + $scope.isSchemaRoot = false; + + delete $scope.enableNestedDocs; + delete $scope.enableDynamicFields; + delete $scope.enableFieldGuessing; + + // schema editor + $scope.showFieldDetails = false; + $scope.selectedNode = null; + $scope.selectedUpdated = false; + delete $scope.updateStatusMessage; + + // text field analysis + $scope.showAnalysis = false; + $scope.sampleDocId = null; + $scope.indexText = ""; + $scope.result = {}; + + // publish vars + delete $scope.newCollection; + $scope.reloadOnPublish = "true"; + + // query form + $scope.query = {q: '*:*', sortBy: 'score', sortDir: 'desc'}; + + SchemaDesigner.get({path: "configs"}, function (data) { + + $scope.schemas = []; + $scope.publishedSchemas = ["_default"]; + + for (var s in data.configSets) { + // 1 means published but not editable + if (data.configSets[s] !== 1) { + $scope.schemas.push(s); + } + + // 0 means not published yet (so can't copy from it yet) + if (data.configSets[s] > 0) { + $scope.publishedSchemas.push(s); + } + } + + $scope.schemas.sort(); + $scope.publishedSchemas.sort(); + + // if no schemas available to select, open the pop-up immediately + if ($scope.schemas.length === 0) { + $scope.firstSchemaMessage = true; + $scope.showNewSchemaDialog(); + } + }, function(e) { + if (e.status === 401 || e.status === 403) { + $scope.isSchemaDesignerEnabled = false; + $scope.hideAll(); + } + }); + }; + + $scope.selectNodeInTree = function(nodeId) { + nodeId = stripAnchorSuffix(nodeId); + if (!nodeId) return; + + var jst = $('#schemaJsTree').jstree(true); + if (jst) { + var selectedId = null; + var selected_node = jst.get_selected(); + if (selected_node && selected_node.length > 0) { + selectedId = selected_node[0]; + } + if (selectedId) { + try { + jst.deselect_node(selectedId); + } catch (err) { + // just ignore + //console.log("error deselecting "+selectedId); + } + } + + try { + jst.select_node(nodeId, true); + } catch (err) { + // just ignore, some low-level tree issue + //console.log("error selecting "+nodeId); + } + } + }; + + $scope.loadFile = function (event) { + var t = event.target || event.srcElement || event.currentTarget; + if (t && t.text) { + $scope.onSelectFileNode("files/" + t.text, true); + } + }; + + $scope.confirmEditSchema = function () { + $scope.showConfirmEditSchema = false; + if ($scope.hasDocsOnServer || $scope.published) { + $scope.doAnalyze(); + } else { + $scope.sampleMessage = "Please upload or paste some sample documents to analyze for building the '" + $scope.currentSchema + "' schema."; + } + }; + + $scope.cancelEditSchema = function () { + $scope.currentSchema = ""; + $scope.showConfirmEditSchema = false; + }; + + $scope.loadSchema = function () { + + if (!$scope.currentSchema) { + return; + } + + $scope.resetSchema(); + var params = {path: "info", configSet: $scope.currentSchema}; + SchemaDesigner.get(params, function (data) { + $scope.currentSchema = data.configSet; + $("#select-schema").trigger("chosen:updated"); + + $scope.confirmSchema = data.configSet; + $scope.collectionsForConfig = data.collections; + $scope.hasDocsOnServer = data.numDocs > 0; + $scope.published = data.published; + $scope.initDesignerSettingsFromResponse(data); + if ($scope.collectionsForConfig && $scope.collectionsForConfig.length > 0) { + $scope.showConfirmEditSchema = true; + } else { + if ($scope.hasDocsOnServer || $scope.published) { + $scope.doAnalyze(); + } else { + $scope.sampleMessage = "Please upload or paste some sample documents to build the '" + $scope.currentSchema + "' schema."; + } + } + }, $scope.errorHandler); + }; + + $scope.showNewSchemaDialog = function () { + $scope.hideAll(); + $scope.showNewSchema = true; + $scope.newSchema = ""; + }; + + $scope.addSchema = function () { + $scope.firstSchemaMessage = false; + delete $scope.addMessage; + + if (!$scope.newSchema) { + $scope.addMessage = "Please provide a schema name!"; + return; + } + + $scope.newSchema = $scope.newSchema.trim(); + if ($scope.newSchema.length > 50) { + $scope.addMessage = "Schema name be 50 characters or less"; + return; + } + + if ($scope.newSchema.indexOf(" ") !== -1 || $scope.newSchema.indexOf("/") !== -1) { + $scope.addMessage = "Schema name should not contain spaces or /"; + return; + } + + if ($scope.publishedSchemas.includes($scope.newSchema) || $scope.schemas.includes($scope.newSchema)) { + $scope.addMessage = "Schema '" + $scope.newSchema + "' already exists!"; + return; + } + + delete $scope.addMessage; + if (!$scope.copyFrom) { + $scope.copyFrom = "_default"; + } + + $scope.resetSchema(); + $scope.schemas.push($scope.newSchema); + $scope.showNewSchema = false; + $scope.currentSchema = $scope.newSchema; + $scope.sampleMessage = "Please upload or paste some sample documents to analyze for building the '" + $scope.currentSchema + "' schema."; + + SchemaDesigner.post({path: "prep", configSet: $scope.newSchema, copyFrom: $scope.copyFrom}, null, function (data) { + $scope.initDesignerSettingsFromResponse(data); + }, $scope.errorHandler); + }; + + $scope.cancelAddSchema = function () { + delete $scope.addMessage; + delete $scope.sampleMessage; + + $scope.showNewSchema = false + }; + + $scope.hideAll = function () { + delete $scope.helpId; + $scope.showPublish = false; + $scope.showDiff = false; + $scope.showNewSchema = false; + $scope.showAddField = false; + $scope.showAddDynamicField = false; + $scope.showAddCopyField = false; + $scope.showAnalysis = false; + // add more dialogs here + }; + + $scope.showHelp = function (id) { + if ($scope.helpId && ($scope.helpId === id || id === '')) { + delete $scope.helpId; + } else { + $scope.helpId = id; + } + }; + + $scope.hideData = function () { + $scope.showData = false; + }; + + $scope.rootChanged = function () { + $scope.selectedUpdated = true; + $scope.selectedType = "Schema"; + }; + + $scope.updateUniqueKey = function () { + delete $scope.schemaRootMessage; + var jst = $('#schemaJsTree').jstree(); + if (jst) { + var node = jst.get_node("field/" + $scope.updateUniqueKeyField); + if (node && node.a_attr) { + var attrs = node.a_attr; + if (attrs.multiValued || attrs.tokenized || !attrs.stored || !attrs.indexed) { + $scope.schemaRootMessage = "Field '" + $scope.updateUniqueKeyField + + "' cannot be used as the uniqueKey field! Must be single-valued, stored, indexed, and not tokenized."; + $scope.updateUniqueKeyField = $scope.uniqueKeyField; + return; + } + } + } + $scope.uniqueKeyField = $scope.updateUniqueKeyField; + $scope.selectedUpdated = true; + $scope.selectedType = "Schema"; + }; + + $scope.resetSchema = function () { + $scope.hideAll(); + $scope.analysisVerbose = false; + $scope.showSchemaActions = false; + $scope.showAnalysis = false; + $scope.showFieldDetails = false; + $scope.hasDocsOnServer = false; + $scope.query = {q: '*:*', sortBy: 'score', sortDir: 'desc'}; + $scope.schemaVersion = -1; + + $scope.updateWorking = false; + $scope.isVersionMismatch = false; + delete $scope.updateStatusMessage; + delete $scope.designerAPIError; + delete $scope.designerAPIErrorDetails; + delete $scope.selectedFacets; + delete $scope.sampleDocuments; + delete $scope.selectedNode; + delete $scope.queryResultsTree; + }; + + $scope.onSchemaUpdated = function (schema, data, nodeId) { + $scope.hasDocsOnServer = data.numDocs && data.numDocs > 0; + $scope.uniqueKeyField = data.uniqueKeyField; + $scope.updateUniqueKeyField = $scope.uniqueKeyField; + $scope.initDesignerSettingsFromResponse(data); + + var fieldTypes = fieldTypesToTree(data.fieldTypes); + var files = filesToTree(data.files); + + var rootChildren = []; + $scope.fieldsSrc = fieldsToTree(data.fields); + $scope.fieldsNode = { + "id": "fields", + "text": "Fields", + "state": {"opened": true}, + "a_attr": {"href": "fields"}, + "children": $scope.fieldsSrc + }; + rootChildren.push($scope.fieldsNode); + + if ($scope.enableDynamicFields === "true") { + $scope.dynamicFieldsSrc = fieldsToTree(data.dynamicFields); + $scope.dynamicFieldsNode = { + "id": "dynamicFields", + "text": "Dynamic Fields", + "a_attr": {"href": "dynamicFields"}, + "children": $scope.dynamicFieldsSrc + }; + rootChildren.push($scope.dynamicFieldsNode); + } else { + delete $scope.dynamicFieldsNode; + delete $scope.dynamicFieldsSrc; + } + + rootChildren.push({"id":"fieldTypes", "text": "Field Types", "a_attr": {"href": "fieldTypes"}, "children": fieldTypes}); + rootChildren.push(files); + + var tree = [{"id":"/", "text": schema, "a_attr": {"href": "/"}, "state":{"opened": true}, "children": rootChildren}]; + + $scope.fields = data.fields; + $scope.fieldNames = data.fields.map(f => f.name).sort(); + $scope.possibleIdFields = data.fields.filter(f => f.indexed && f.stored && !f.tokenized).map(f => f.name).sort(); + $scope.sortableFields = data.fields.filter(f => (f.indexed || f.docValues) && !f.multiValued && !f.tokenized).map(f => f.name).sort(); + $scope.sortableFields.push("score"); + + $scope.facetFields = data.fields.filter(f => (f.indexed || f.docValues) && !f.tokenized && f.name !== '_version_').map(f => f.name).sort(); + $scope.hlFields = data.fields.filter(f => f.stored && f.tokenized).map(f => f.name).sort(); + + $scope.schemaVersion = data.schemaVersion; + $scope.currentSchema = data.configSet; + $scope.fieldTypes = fieldTypes; + $scope.core = data.core; + $scope.schemaTree = tree; + $scope.refreshTree(); + + $scope.collectionsForConfig = data.collectionsForConfig; + + if (data.docIds) { + $scope.sampleDocIds = data.docIds; + } else { + $scope.sampleDocIds = []; + } + + // Load the Luke schema + Luke.schema({core: data.core}, function (schema) { + Luke.raw({core: data.core}, function (index) { + $scope.luke = mergeIndexAndSchemaData(index, schema.schema); + $scope.types = Object.keys(schema.schema.types); + $scope.showSchemaActions = true; + if (!nodeId) { + nodeId = "/"; + } + // re-apply the filters on the updated schema + $scope.applyTreeFilterOption(); + $scope.onSelectSchemaTreeNode(nodeId); + + $scope.updateWorking = false; + + if (data.updateError != null) { + $scope.onError(data.updateError, data.updateErrorCode, data.errorDetails); + } else { + if ($scope.selectedUpdated) { + $scope.selectedUpdated = false; + $scope.updateStatusMessage = "Changes applied successfully."; + var waitMs = 3000; + if (data.rebuild) { + $scope.updateStatusMessage += " Did full re-index of sample docs due to incompatible update."; + waitMs = 5000; // longer message, more time to read + } + + if (data.analysisError) { + var updateType = data["updateType"]; + var updatedObject = data[updateType]; + var updatedName = updatedObject && updatedObject.name ? updatedObject.name : ""; + var warnMsg = "Changes to "+updateType+" "+updatedName+" applied, but required the temp collection to be deleted " + + "and re-created due to an incompatible Lucene change, see details below."; + $scope.onWarning(warnMsg, data.analysisError); + } else { + $timeout(function () { delete $scope.updateStatusMessage; }, waitMs); + } + } else { + var source = data.sampleSource; + if (source) { + if (source === "paste") { + source = "pasted sample" + } else if (source === "blob") { + source = "previous upload stored on the server" + } + if (data.numDocs > 0) { + $scope.updateStatusMessage = "Analyzed "+data.numDocs+" docs from "+source; + } else { + $scope.updateStatusMessage = "Schema '"+$scope.currentSchema+"' loaded."; + } + } + $timeout(function () { + delete $scope.updateStatusMessage; + }, 5000); + } + } + + // re-fire the current query to reflect the updated schema + $scope.doQuery(); + $scope.selectNodeInTree(nodeId); + }); + }); + }; + + $scope.toggleAddField = function (type) { + if ($scope.showAddField) { + $scope.hideAll(); + } else { + $scope.hideAll(); + $scope.showAddField = true; + $scope.adding = type; + + $scope.newField = { + stored: "true", + indexed: "true", + uninvertible: "true", + docValues: "true" + } + + if (type === "field") { + $scope.newField.type = "string"; + } + + delete $scope.addErrors; + } + }; + + function applyConstraintsOnField(f) { + + if (!f.docValues) { + delete f.useDocValuesAsStored; + } + + if (!f.docValues && !f.uninvertible) { + delete f.sortMissingLast; // remove this setting if no docValues / uninvertible + } + + if (f.indexed) { + if (f.omitTermFreqAndPositions && !f.omitPositions) { + delete f.omitPositions; // :shrug ~ see SchemaField ln 295 + } + if (!f.termVectors) { + delete f.termPositions; + delete f.termOffsets; + delete f.termPayloads; + } + } else { + // if not indexed, a bunch of fields are false + f.tokenized = false; + f.uninvertible = false; + + // drop these from the request + delete f.termVectors; + delete f.termPositions; + delete f.termOffsets; + delete f.termPayloads; + delete f.omitNorms; + delete f.omitPositions; + delete f.omitTermFreqAndPositions; + delete f.storeOffsetsWithPositions; + } + + return f; + } + + $scope.addField = function () { + + // validate the form input + $scope.addErrors = []; + if (!$scope.newField.name) { + $scope.addErrors.push($scope.adding + " name is required!"); + } + + if ($scope.newField.name.indexOf(" ") != -1) { + $scope.addErrors.push($scope.adding + " name should not have whitespace"); + } + + var command = "add-field-type"; + if ("field" === $scope.adding) { + + if ($scope.fieldNames.includes($scope.newField.name)) { + $scope.addErrors.push("Field '" + $scope.newField.name + "' already exists!"); + return; + } + + // TODO: is this the correct logic for detecting dynamic? Probably good enough for the designer + var isDynamic = $scope.newField.name.startsWith("*") || $scope.newField.name.endsWith("*"); + if (isDynamic) { + if ($scope.luke && $scope.luke.dynamic_fields[$scope.newField.name]) { + $scope.addErrors.push("dynamic field '" + $scope.newField.name + "' already exists!"); + } + } else { + if ($scope.luke && $scope.luke.fields[$scope.newField.name]) { + $scope.addErrors.push("field '" + $scope.newField.name + "' already exists!"); + } + } + + if (!$scope.newField.type) { + $scope.addErrors.push("field type is required!"); + } + + command = isDynamic ? "add-dynamic-field" : "add-field"; + } else if ("type" === $scope.adding) { + if ($scope.types.includes($scope.newField.name)) { + $scope.addErrors.push("Type '" + $scope.newField.name + "' already exists!"); + } + + if (!$scope.newField.class) { + $scope.addErrors.push("class is required when creating a new field type!"); + } + } + + var addData = {}; + addData[command] = applyConstraintsOnField($scope.newField); + if ($scope.textAnalysisJson) { + var text = $scope.textAnalysisJson.trim(); + if (text.length > 0) { + text = text.replace(/\s+/g, ' '); + if (!text.startsWith("{")) { + text = "{ " + text + " }"; + } + try { + var textJson = JSON.parse(text); + if (textJson.analyzer) { + addData[command].analyzer = textJson.analyzer; + } else { + if (!textJson.indexAnalyzer || !textJson.queryAnalyzer) { + $scope.addErrors.push("Text analysis JSON should define either an 'analyzer' or an 'indexAnalyzer' and 'queryAnalyzer'"); + return; + } + addData[command].indexAnalyzer = textJson.indexAnalyzer; + addData[command].queryAnalyzer = textJson.queryAnalyzer; + } + } catch (e) { + $scope.addErrors.push("Failed to parse analysis as JSON due to: " + e.message + + "; expected JSON object with either an 'analyzer' or 'indexAnalyzer' and 'queryAnalyzer'"); + return; + } + } + } + + if ($scope.addErrors.length > 0) { + return; + } + delete $scope.addErrors; // no errors! + + SchemaDesigner.post({ + path: "add", + configSet: $scope.currentSchema, + schemaVersion: $scope.schemaVersion + }, addData, function (data) { + if (data.errors) { + $scope.addErrors = data.errors[0].errorMessages; + if (typeof $scope.addErrors === "string") { + $scope.addErrors = [$scope.addErrors]; + } + } else { + delete $scope.textAnalysisJson; + $scope.added = true; + $timeout(function () { + $scope.showAddField = false; + $scope.added = false; + var nodeId = "/"; + if ("field" === $scope.adding) { + nodeId = "field/" + data[command]; + } else if ("type" === $scope.adding) { + nodeId = "type/" + data[command]; + } + $scope.onSchemaUpdated(data.configSet, data, nodeId); + }, 500); + } + }, $scope.errorHandler); + } + + function toSortedNameAndTypeList(fields, typeAttr) { + var list = []; + var keys = Object.keys(fields); + for (var f in keys) { + var field = fields[keys[f]]; + var type = field[typeAttr]; + if (type) { + list.push(field.name + ": "+type); + } else { + list.push(field.name); + } + } + return list.sort(); + } + + function toSortedFieldList(fields) { + var list = []; + var keys = Object.keys(fields); + for (var f in keys) { + list.push(fields[keys[f]]); + } + return list.sort((a, b) => (a.name > b.name) ? 1 : -1); + } + + $scope.toggleDiff = function (event) { + if ($scope.showDiff) { + // toggle, close dialog + $scope.showDiff = false; + return; + } + + if (event) { + var t = event.target || event.currentTarget; + var leftPos = t.getBoundingClientRect().left - 600; + if (leftPos < 0) leftPos = 0; + $('#show-diff-dialog').css({left: leftPos}); + } + + SchemaDesigner.get({ path: "diff", configSet: $scope.currentSchema }, function (data) { + var diff = data.diff; + + var dynamicFields = diff.dynamicFields; + var enableDynamicFields = data.enableDynamicFields !== null ? data.enableDynamicFields : true; + if (!enableDynamicFields) { + dynamicFields = null; + } + + $scope.diffSource = data["diff-source"]; + $scope.schemaDiff = { + "fieldsDiff": diff.fields, + "addedFields": [], + "removedFields": [], + "fieldTypesDiff": diff.fieldTypes, + "removedTypes": [], + "dynamicFieldsDiff": dynamicFields, + "copyFieldsDiff": diff.copyFields + } + if (diff.fields && diff.fields.added) { + $scope.schemaDiff.addedFields = toSortedFieldList(diff.fields.added); + } + if (diff.fields && diff.fields.removed) { + $scope.schemaDiff.removedFields = toSortedNameAndTypeList(diff.fields.removed, "type"); + } + if (diff.fieldTypes && diff.fieldTypes.removed) { + $scope.schemaDiff.removedTypes = toSortedNameAndTypeList(diff.fieldTypes.removed, "class"); + } + + $scope.schemaDiffExists = !(diff.fields == null && diff.fieldTypes == null && dynamicFields == null && diff.copyFields == null); + $scope.showDiff = true; + }, $scope.errorHandler); + } + + $scope.togglePublish = function (event) { + if (event) { + var t = event.target || event.currentTarget; + var leftPos = t.getBoundingClientRect().left - 515; + if (leftPos < 0) leftPos = 0; + $('#publish-dialog').css({left: leftPos}); + } + + $scope.showDiff = false; + $scope.showPublish = !$scope.showPublish; + delete $scope.publishErrors; + + $scope.disableDesigner = "false"; + + if ($scope.showPublish && !$scope.newCollection) { + $scope.newCollection = {numShards: 1, replicationFactor: 1, indexToCollection: "true"}; + } + }; + + $scope.toggleAddCopyField = function () { + if ($scope.showAddCopyField) { + $scope.hideAll(); + $scope.showFieldDetails = true; + } else { + $scope.hideAll(); + $scope.showAddCopyField = true; + $scope.showFieldDetails = false; + + $scope.copyField = {}; + delete $scope.addCopyFieldErrors; + } + } + $scope.addCopyField = function () { + delete $scope.addCopyFieldErrors; + var data = {"add-copy-field": $scope.copyField}; + SchemaDesigner.post({ + path: "add", + configSet: $scope.currentSchema, + schemaVersion: $scope.schemaVersion + }, data, function (data) { + if (data.errors) { + $scope.addCopyFieldErrors = data.errors[0].errorMessages; + if (typeof $scope.addCopyFieldErrors === "string") { + $scope.addCopyFieldErrors = [$scope.addCopyFieldErrors]; + } + } else { + $scope.showAddCopyField = false; + // TODO: + //$timeout($scope.refresh, 1500); + } + }, $scope.errorHandler); + } + + $scope.toggleAnalyzer = function (analyzer) { + analyzer.show = !analyzer.show; + } + + $scope.initTypeAnalysisInfo = function (typeName) { + $scope.analysis = getAnalysisInfo($scope.luke, {type: true}, typeName); + if ($scope.analysis && $scope.analysis.data) { + $scope.className = $scope.analysis.data.className + } + $scope.editAnalysis = "Edit JSON"; + $scope.showAnalysisJson = false; + delete $scope.analysisJsonText; + }; + + $scope.toggleVerbose = function () { + $scope.analysisVerbose = !$scope.analysisVerbose; + }; + + $scope.updateSampleDocId = function () { + $scope.indexText = ""; + $scope.result = {}; + + if (!$scope.selectedNode) { + return; + } + + var field = $scope.selectedNode.name; + var params = {path: "sample"}; + params.configSet = $scope.currentSchema; + params.uniqueKeyField = $scope.uniqueKeyField; + params.field = field; + + if ($scope.sampleDocId) { + params.docId = $scope.sampleDocId; + } // else the server will pick the first doc with a non-empty text value for the desired field + + SchemaDesigner.get(params, function (data) { + $scope.sampleDocId = data[$scope.uniqueKeyField]; + $scope.indexText = data[field]; + if (data.analysis && data.analysis["field_names"]) { + $scope.result = processFieldAnalysisData(data.analysis["field_names"][field]); + } + }, $scope.errorHandler); + }; + + $scope.changeLanguages = function () { + $scope.selectedUpdated = true; + $scope.selectedType = "Schema"; + }; + + function getType(typeName) { + if ($scope.fieldTypes) { + for (i in $scope.fieldTypes) { + if ($scope.fieldTypes[i].text === typeName) { + return $scope.fieldTypes[i]; + } + } + } + return null; + } + + $scope.refreshTree = function() { + var jst = $('#schemaJsTree').jstree(true); + if (jst) { + jst.refresh(); + } + }; + + $scope.onSchemaTreeLoaded = function (id) { + //console.log(">> on tree loaded"); + }; + + $scope.updateFile = function () { + var nodeId = "files/" + $scope.selectedFile; + var params = {path: "file", file: $scope.selectedFile, configSet: $scope.currentSchema}; + + $scope.updateWorking = true; + $scope.updateStatusMessage = "Updating file ..."; + + SchemaDesigner.post(params, $scope.fileNodeText, function (data) { + if (data.updateFileError) { + if (data[$scope.selectedFile]) { + $scope.fileNodeText = data[$scope.selectedFile]; + } + $scope.updateFileError = data.updateFileError; + } else { + delete $scope.updateFileError; + $scope.updateStatusMessage = "File '"+$scope.selectedFile+"' updated."; + $scope.onSchemaUpdated(data.configSet, data, nodeId); + } + }, $scope.errorHandler); + }; + + $scope.onSelectFileNode = function (id, doSelectOnTree) { + $scope.selectedFile = id.startsWith("files/") ? id.substring("files/".length) : id; + + var params = {path: "file", file: $scope.selectedFile, configSet: $scope.currentSchema}; + SchemaDesigner.get(params, function (data) { + $scope.fileNodeText = data[$scope.selectedFile]; + $scope.isLeafNode = false; + if (doSelectOnTree) { + delete $scope.selectedNode; + $scope.isLeafNode = false; + $scope.showFieldDetails = true; + delete $scope.sampleDocId; + $scope.showAnalysis = false; + $scope.selectNodeInTree(id); + } + }, $scope.errorHandler); + }; + + function fieldNodes(src, type) { + var nodes = []; + for (var c in src) { + var childNode = src[c]; + if (childNode && childNode.a_attr) { + var a = childNode.a_attr; + var stored = a.stored || (a.docValues && a.useDocValuesAsStored); + var obj = {"name":a.name, "indexed":a.indexed, "docValues": a.docValues, + "multiValued":a.multiValued, "stored":stored, "tokenized": a.tokenized}; + if (type === "field" || type === "dynamicField") { + obj.type = a.type; + } else if (type === "type") { + obj.class = a.class; + } + nodes.push(obj); + } + } + return nodes; + } + + function stripAnchorSuffix(id) { + if (id && id.endsWith("_anchor")) { + id = id.substring(0, id.length - "_anchor".length); + } + return id; + } + + $scope.onSelectSchemaTreeNode = function (id) { + id = stripAnchorSuffix(id); + $scope.showFieldDetails = false; + $scope.isSchemaRoot = false; + $scope.isLeafNode = false; + delete $scope.containerNodeLabel; + delete $scope.containerNode; + delete $scope.containerNodes; + delete $scope.selectedFile; + + if (id === "/") { + $scope.selectedType = "Schema"; + $scope.selectedNode = null; + $scope.isSchemaRoot = true; + $scope.isLeafNode = false; + $scope.isContainerNode = false; + $scope.showFieldDetails = true; + delete $scope.sampleDocId; + $scope.showAnalysis = false; + + if (!$scope.treeFilter) { + $scope.treeFilter = "type"; + $scope.treeFilterOption = "*"; + $scope.initTreeFilters(); + } + return; + } + + var jst = $('#schemaJsTree').jstree(true); + if (!jst) { + return; + } + + var node = jst.get_node(id); + if (!node) { + return; + } + + if (id === "files") { + $scope.selectedNode = null; + $scope.isLeafNode = false; + return; + } + + if (id.indexOf("/") === -1) { + $scope.selectedNode = null; + $scope.isLeafNode = false; + $scope.containerNode = id; + + if (id === "fields") { + $scope.containerNodes = fieldNodes($scope.fieldsNode ? $scope.fieldsNode.children : $scope.fieldsSrc, "field"); + } else if (id === "dynamicFields") { + $scope.containerNodes = fieldNodes($scope.dynamicFieldsNode ? $scope.dynamicFieldsNode.children : $scope.dynamicFieldsSrc, "dynamicField"); + } else if (id === "fieldTypes") { + $scope.containerNodes = fieldNodes($scope.fieldTypes, "type"); + } + + $scope.containerNodeLabel = node.text; + $scope.showFieldDetails = true; + delete $scope.sampleDocId; + $scope.showAnalysis = false; + return; + } + + if (id.startsWith("files/")) { + $scope.selectedNode = null; + $scope.isLeafNode = false; + delete $scope.sampleDocId; + $scope.showAnalysis = false; + if (node.children.length === 0) { + // file + $scope.showFieldDetails = true; + $scope.onSelectFileNode(id, false); + } else { + // folder + $scope.showFieldDetails = false; + delete $scope.selectedFile; + } + return; + } + + delete $scope.selectedFile; + $scope.selectedNode = node["a_attr"]; // all the info we need is in the a_attr object + if (!$scope.selectedNode) { + // a node in the tree that isn't a field was selected, just ignore + return; + } + + $scope.selectedNode.fieldType = getType($scope.selectedNode.type); + $scope.isLeafNode = true; + + var nodeType = id.substring(0, id.indexOf("/")); + var name = null; + if (nodeType === "field") { + $scope.selectedType = "Field"; + name = $scope.selectedNode.type; + } else if (nodeType === "dynamic") { + $scope.selectedType = "Dynamic Field"; + } else if (nodeType === "type") { + $scope.selectedType = "Type"; + name = $scope.selectedNode.name; + } + + if (name) { + $scope.initTypeAnalysisInfo(name, "type"); + } + + // apply some sanity to the checkboxes + $scope.selectedNode = applyConstraintsOnField($scope.selectedNode); + $scope.showFieldDetails = true; + + if (nodeType === "field" && $scope.selectedNode.tokenized && $scope.selectedNode.stored) { + $scope.showAnalysis = true; + $scope.updateSampleDocId(); + } else { + $scope.showAnalysis = false; + $scope.indexText = ""; + $scope.result = {}; + } + }; + + function addFileNode(dirs, parent, f) { + var path = f.split("/"); + if (path.length === 1) { + if (!parent.children) { + parent.children = []; + dirs.push(parent); // now parent has children, so track in dirs ... + } + var nodeId = parent.id + "/" + f; + parent.children.push({"text": f, "id": nodeId, "a_attr": {"href": nodeId}}); + } else { + // get the parent for this path + var parentId = "files/" + path.slice(0, path.length - 1).join("/"); + var dir = null; + for (var d in dirs) { + if (dirs[d].id === parentId) { + dir = dirs[d]; + break; + } + } + if (!dir) { + dir = {"text": path[0], "id": parentId, "a_attr": {"href": parentId}, "children": []}; + dirs.push(dir); + parent.children.push(dir); + } + + // walk down the next level in this path + addFileNode(dirs, dir, path.slice(1).join("/")); + } + } + + // transform a flat list structure into the nested tree structure + function filesToTree(files) { + var filesNode = {"text": "Files", "a_attr": {"href": "files"}, "id": "files", "children": []}; + if (files) { + var dirs = []; // lookup for known dirs by path since nodes don't keep a ref to their parent node + for (var i in files) { + // hide the configoverlay.json from the UI + if (files[i] === "configoverlay.json") { + continue; + } + + addFileNode(dirs, filesNode, files[i]); + } + delete dirs; + } + return filesNode; + } + + function fieldsToTree(fields) { + var children = []; + if (fields) { + for (var i in fields) { + var id = "field/" + fields[i].name; + fields[i].href = id; + var text = fields[i].name; + if (fields[i].name === $scope.uniqueKeyField) { + text += "*"; // unique key field + } + children.push({"text": text, "a_attr": fields[i], "id": id}); + } + } + return children; + } + + function fieldTypesToTree(types) { + var children = []; + for (var i in types) { + var ft = types[i] + var id = "type/" + ft.name; + ft.href = id; + children.push({"text": ft.name, "a_attr": ft, "id": id}); + } + return children; + } + + $scope.onSampleDocumentsChanged = function () { + $scope.hasDocsOnServer = false; // so the updates get sent on next analyze action + }; + + $scope.initDesignerSettingsFromResponse = function (data) { + $scope.enableDynamicFields = data.enableDynamicFields !== null ? "" + data.enableDynamicFields : "true"; + $scope.enableFieldGuessing = data.enableFieldGuessing !== null ? "" + data.enableFieldGuessing : "true"; + $scope.enableNestedDocs = data.enableNestedDocs !== null ? "" + data.enableNestedDocs : "false"; + $scope.languages = data.languages !== null && data.languages.length > 0 ? data.languages : ["*"]; + $scope.copyFrom = data.copyFrom !== null ? data.copyFrom : "_default"; + }; + + $scope.doAnalyze = function (nodeId) { + delete $scope.sampleMessage; + + var schema = $scope.currentSchema; + if (schema) { + delete $scope.copyFrom; + } else { + schema = $scope.newSchema; + if (!$scope.copyFrom) { + $scope.copyFrom = "_default"; + } + } + + if (!schema) { + return; + } + + var params = {path: "analyze", configSet: schema}; + if ($scope.schemaVersion && $scope.schemaVersion !== -1) { + params.schemaVersion = $scope.schemaVersion; + } + + if ($scope.enableDynamicFields) { + params.enableDynamicFields = $scope.enableDynamicFields; + } + if ($scope.enableFieldGuessing) { + params.enableFieldGuessing = $scope.enableFieldGuessing; + } + if ($scope.enableNestedDocs) { + params.enableNestedDocs = $scope.enableNestedDocs; + } + + if ($scope.languages && $scope.languages.length > 0) { + params.languages = $scope.languages; + } + + if ($scope.copyFrom) { + params.copyFrom = $scope.copyFrom; + } + + $scope.updateWorking = true; + if ($scope.selectedUpdated) { + $scope.updateStatusMessage = "Applying " + $scope.selectedType + " updates ..." + } else { + $scope.updateStatusMessage = "Analyzing your sample data, schema will load momentarily ..." + } + + if (!nodeId && $scope.selectedNode) { + nodeId = $scope.selectedNode.id; + } + + // a bit tricky ... + // so users can upload a file or paste in docs + // if they upload a file containing a small (<15K) of text data, then we'll show it in the textarea + // they can change the text and re-analyze too + // if no changes or nothing uploaded, the server-side uses the latest sample data stored in the blob store + if ($scope.fileUpload) { + var file = $scope.fileUpload; + var fd = new FormData(); + fd.append('file', file); + SchemaDesigner.upload(params, fd, function (data) { + $("#upload-file").val(""); + delete $scope.fileUpload; + $scope.onSchemaUpdated(schema, data, nodeId); + }, $scope.errorHandler); + } else { + // don't need to keep re-posting the same sample if already stored in the blob store + var postData = null; + if (!$scope.hasDocsOnServer) { + postData = $scope.sampleDocuments; + if (!postData && !$scope.published) { + return; + } + } + + var respHandler = function (data) { + $scope.onSchemaUpdated(schema, data, nodeId); + }; + + // TODO: need a better approach to detecting the content type from text content + var contentType = "text/plain"; + if (postData != null) { + var txt = postData.trim(); + if ((txt.startsWith("[") && txt.includes("]")) || (txt.startsWith("{") && txt.includes("}"))) { + contentType = "application/json" + } else if (txt.startsWith("<") || txt.includes("") || txt.includes(" +
    +

     Current user not authorized to use the Schema Designer!

    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    + + +
    {{updateStatusMessage}}
    + +
    + +

    +

    + +

    + +

    +

    +

    + +

    +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + + Show omit options + Hide omit options + +

    + +
    + +

    + +

    + +

    + +

    + +

    + +

    +
    + +

    + + Show term vector options + Hide term vector options + +

    +
    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +

    + +
    + +

    + + Show sort options + Show sort options + +

    +
    +

    + +

    + +

    + +

    + +
    + +

    + + Show text analysis JSON + Hide text analysis JSON + +

    +
    + +
    + +

    + + +

    + +
    +
    {{error}}
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    + +
    +

     {{designerAPIError}}

    +
    +
    + + +
    +
    + +
    +

     {{apiWarning}}

    +
    +
    + +
    +
    + +
    +
    +

    No differences with {{diffSource}} found.

    +
    + {{fieldsDiff=schemaDiff.fieldsDiff;""}} +

    Found differences with {{diffSource}}:

    +
    +
    +

    Updated Fields

    + + + + + + + + + + + +
    NameOldNew
    {{ field }}

    {{fieldDiff[0] | json}}

    {{fieldDiff[1] | json}}

    +
    +
    +

    New Fields

    + + + + + + + + + + + + + + + + + + + + + +
    NameTypeIndexedStoredMultiValuedDocValuesTokenized
    {{f.name}}{{f.type}}
    +
    +
    +

    Removed Fields

    +
      +
    • +

      {{f}}

      +
    • +
    +
    +
    + {{fieldTypesDiff=schemaDiff.fieldTypesDiff;""}} +
    +
    +

    Updated Field Types

    + + + + + + + + + + + +
    NameOldNew
    {{ fieldType }}

    {{fieldTypeDiff[0] | json}}

    {{fieldTypeDiff[1] | json}}

    +
    +
    +

    New Field Types

    +
      +
    • +

      {{fieldtype | json}}

      +
    • +
    +
    +
    +

    Removed Field Types

    +
      +
    • +

      {{fieldtype}}

      +
    • +
    +
    +
    + {{dynamicFieldsDiff=schemaDiff.dynamicFieldsDiff;""}} +
    +
    +

    Updated Dynamic Fields

    + + + + + + + + + + + +
    NameOldNew
    {{ dfield }}

    {{dfieldDiff[0] | json}}

    {{dfieldDiff[1] | json}}

    +
    +
    +

    New Dynamic Fields

    +
      +
    • +

      {{dfield | json}}

      +
    • +
    +
    +
    +

    Removed Dynamic Fields

    +
      +
    • +

      {{dfield.name}}

      +
    • +
    +
    +
    + {{copyFieldsDiff=schemaDiff.copyFieldsDiff;""}} +
    +

    Copy Fields

    + + + + + + + + + + + + + +
    SourceDestination

    {{cfield.source}}

    {{cfield.dest}}

    {{cfield.source}}

    {{cfield.dest}}

    +
    + +
    + +
    +
    + +
    +

    Publish schema and associated configs to Zookeeper as a Solr ConfigSet.

    +
    +

    Affected collections:

    +
      +
    • {{coll}}
    • +
    +
    No existing collections
    +
    +
    +
    + + +
    +
    + +
    +

    Add new collection with published config?

    +
    +

    +

    + +

    +

    + +

    +

    +
    +
    + + +
    +
    +
    + + +
    +
    {{error}}
    +
    + + +
    +
    + +
    +

    Warning: You've chosen to load an existing schema that is already being used by active collections. Making changes to the '{{confirmSchema}}' schema will impact existing documents in these collections. Please proceed with caution.

    +

    Collections using the {{confirmSchema}} schema:

    +
    • {{coll}}
    +

    + + +

    +
    + +
    +

    Get started building your search app by defining a new schema. A schema defines all the fields in your search index. Solr comes with a _default schema that provides a good starting point to customize based on your specific data.

    +
    +

    +
    + +
    +
    +

    Copy an existing Configset (schema, solrconfig.xml, and supporting files) as the starting point for your new schema. The _default Configset includes a schema with field guessing enabled, dynamic fields for common field types, and field types for analyzing text data for a number of common languages supported by Lucene. For more information about Configsets, see:

    +
    +
    +
    +

    {{addMessage}}

    +

    + + +

    +
    +
    +
    +
    +
    + +
    + +
    +
    +

    Sample Documents

    +
    +
    +
    +
    + +
    +
    +

    Upload a JSON, CSS, or XML file containing sample documents or simply paste some sample documents into the text area below; the Schema Designer supports a maximum of 5MB and 1,000 documents. +

    Click on the Analyze Documents button to have Solr determine the schema by looking at the sample values for each field. Sample documents are stored on the server so you can make changes to the schema and Schema Designer will automatically re-index the sample documents to apply the changes. +

    +
    +
    +
    + + +
    +
    +

    {{sampleMessage}}

    + +
    +
    +
    +
    + +
    + +
    +
    +

    Schema Editor

    +
    + Filter fields by:  + + + + + +
    +
    + +
    +
    +
    + + +
    + +
    +
    + +

    {{currentSchema}}

    +
    +
    + + +
    +
    + + +
    +
    +

    By default, schemas copied from the _default schema include field types (and associated files) for all built-in languages. Select the languages needed for your application and the designer will remove all the unnecessary field types for languages you don't need. For more information about text analysis and languages, see: +

    +

    +
    +
    +
    +
    + + + +
    +
    +

    Dynamic fields allow Solr to index fields that you did not explicitly define in your schema. Dynamic fields can make your application less brittle by providing some flexibility in the documents you can add to Solr. It is recommended to keep the default set of dynamic fields enabled for your schema. Unchecking this option removes all dynamic fields from your schema. For more information about dynamic fields, see: +

    +

    +
    +
    +
    +
    + + + +
    +
    +

    Field guessing (aka "schemaless mode") allows Solr to detect the "best" field type for unknown fields encountered during indexing. Field guessing also performs some field transformations, such as removing spaces from field names. If you use the schema designer to create your schema based on sample documents, you may not need to enable this feature. + However, with this feature disabled, you need to make sure the incoming data matches the schema exactly or indexing errors may occur. For more information about schemaless mode, see: +

    +

    +
    +
    +
    +
    + + + +
    +
    +

    Enabling this feature adds the _root_ and _nest_path_ fields to your schema.

    For more information about indexing nested child documents, see: +

    +

    +
    +
    +
    +
    +
    + +
    + +
    +

    {{updateFileError}}

    +
    +
    +
    +

    {{updateSelectedError}}

    +
    +
    +
    {{selectedType}}: {{selectedNode.name}}
    +
    + + +
    +
    +

    The field type defines how Solr should interpret data in a field and how the field can be queried. The properties on each field are inherited from the field type if not explicitly overridden in the field definition. In many cases, it's preferable to choose a different field type instead of overriding the field properties. For example, there's typically a multi-valued version of each type, such as strings is the multi-valued version of the string type. For more information about field types, see: +

    +

    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +

    Copy fields allow you to apply several distinct field types to a single piece of incoming information during indexing. For instance, a common approach is to copy important string fields into the catch-all '_text_' field to enable full-text matches on terms contained in string fields. Provide a comma-delimited list of fields to copy into during indexing. For more information about copy fields, see: +

    +

    +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Name +
    +
    +

    This table provides a list of {{containerNodeLabel}} defined for your schema. Click on the name in the first column to edit properties. Click on {{containerNodeLabel}} in the Schema Editor tree on the left to return to this table view.

    For more information about field properties, see:

    +
    +
    +
    TypeIndexedStoredMultiValuedDocValuesTokenized
    {{f.name}}{{f.type}}
    +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Type +
    +
    +

    This table provides a list of field types defined for your schema. Click on the type name in the first column to edit properties for that type. Changing properties for a type impacts all fields linked to the type. Click on Field Types in the Schema Editor tree on the left to return to this table view.

    For more information about field types, see:

    +
    +
    ClassIndexedStoredMultiValuedDocValuesTokenized
    {{f.name}}{{f.class}}
    +
    +
    +
    +
    + +
    +
    +

    Text Analysis

    +
    +
    This Functionality requires the /analysis/field Handler to be registered and active!
    +
    +
    +
    {{analysisError}}
    +
    +
    +
    + + +
    +
    + + +
    + +
    +
    + + + + + + + + + +
    +
    + {{component.short}} +
    +
    +
    + + + + +
    + + +
    {{ caption }}
    +
    +
    +
    +
    + + + + + + +
    + + + + + + +
    {{value.value}}
    +
    +
    +
     
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Query Tester

    +
    +
    +
    + + + +
    +
    +

    Main query parameter q specifies the ranked matching criteria for documents. If you don't specify a field name in the query, the default text field, typically _text_, is used. + If the query results do not contain expected documents, check how the default text field is populated, typically using copy field directives in the schema. +

    For more information about query parameters, see: +

    +

    +
    +
    +
    +
    + + asc desc + +
    +
    +

    Sort fields must be single-valued and indexed (or have docValues enabled). If an expected field is not present in this list, check the active properties in the schema. +

    For more information about query parameters, see: +

    +

    +
    +
    +
    +
    + + + +
    +
    + Fields must be indexed or have docValues enabled to compute facets.

    For more information about faceting, see: + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Query Results

    +
    +
    + +
    +
    +
    + +
    +
    Copy the documents from the query results to the Sample Documents text area as JSON. This allows you to refine your schema by changing the sample data sourced from the query results.
    +
    +
    +
    + + + + + + + +
    {{row.name}}{{row.name}}{{row.value}}
    +
    +
    +
    +
    +
    +
    + +
    + +
    diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/partials/security.html b/KeywordSearch/solr/server/solr-webapp/webapp/partials/security.html new file mode 100755 index 0000000000..d8d3093dd7 --- /dev/null +++ b/KeywordSearch/solr/server/solr-webapp/webapp/partials/security.html @@ -0,0 +1,308 @@ + +
    +
    +

     Current user is not authenticated! Security panel is disabled.

    +
    + +
    +

     You do not have permission to view the security panel.

    +
    + +
    +

     WARNING: Security is not enabled for this server!

    +
    +

    Use the bin/solr auth command-line tool to enable security and then reload this panel. For more information, see: Using security.json with Solr

    +


    Example usage of bin/solr auth to enable basic authentication:

    +
    +
    +
    +        bin/solr auth enable -type basicAuth -prompt true -z {{zkHost}} -blockUnknown true
    +
    +      
    +
    +
    +

    Create a security.json config file in your Solr home directory and then restart Solr (on all nodes). For more information, see: Using security.json with Solr

    +
    +
    + +
    + +
    +
    +

    Security Settings

    +
    +
    TLS enabled? + Authentication Plugin: {{authenticationPlugin}} +
    +
    +

    When using the MultiAuthPlugin, changes made to Users and Roles, using the panels below, only affect Basic authentication.

    + Users and Roles for the other authentication schemes, such as the Bearer scheme (JWTAuthPlugin), are managed by an external provider. + Thus, not all users with access to the system are displayed below; only users managed by the BasicAuthPlugin are displayed on this screen. +

    +
    +
    +
    +
    + Authorization Plugin: {{authorizationPlugin}}
    +
    + + + + +
    +
    +

    If checked, un-authenticated requests to any Solr endpoint are blocked. If un-checked, then any endpoint that is not protected with a permission will be accessible by anonymous users. Only disable this check if you want to allow un-authenticated access to specific endpoints that are configured with role: null. All other endpoints should be protected with explicit role bindings that require authentication. For more information, see: +

    +
    +
    +
    + +
    +
    +

    If checked, Solr forwards user credentials when making distributed requests to other nodes in the cluster. If un-checked (the default), Solr will use the internal PKI authentication mechanism for distributed requests. For more information, see: +

    +
    +
    +
    +
    +
    + +
    +

     {{securityAPIError}}

    +
    +
    + +
    +
    + +
    +
    {{userDialogHeader}}
    +
    +

    +

    +

    +

    +

    +
    +

    {{validationError}}

    +
    +

    + + +

    +
    +
    + +
    +
    {{roleDialogHeader}}
    +
    +

    +

    + +

    +
    +

    {{validationError}}

    +
    +

    + + +

    +
    +
    + +
    +
    {{permDialogHeader}}
    +
    +
    +
    +
    +

    For requests where multiple permissions match, Solr applies the first permission that matches based on a complex ordering logic. In general, more specific permissions should be listed earlier in the configuration. The permission index (1-based) governs its position in the configuration. To re-order a permission, change the index to desired position. +

    +
    +
    +
    +
    or Custom: +
    +
    +

    Permissions allow you to grant access to protected resources to one or more roles. Solr provides a list of predefined permissions to cover common use cases, such as collection administration. Otherwise, you can define a custom permission for fine-grained control over the API path(s), collection(s), request method(s) and params. +

    +
    +
    +
    +

    +

    +

    +
    + + + + + +
    GET
    POST
    PUT
    DELETE
    +
    +
    +
    +
    +  =  +
    + + +
    +
    +
    +
    +
    +

    {{validationError}}

    +
    +

    + + +

    +
    +
    +
    +
    + +
    +
    +

    Users

    +

     Users are managed by an external provider.

    +
    +
    + Filter users by:  + + +
    + +
    +
    + +
    + + + + + + + + + + + +
    UsernameRoles
    {{u.username}}{{displayList(u.roles)}}
    +
    +
    +
    + +
    +

    Roles

    +

     Roles are managed by an external provider.

    +
    +
    + Filter roles by:  + + +
    + +
    +
    + +
    + + + + + + + + + + + +
    RoleUsers
    {{r.name}}{{displayList(r.users)}}
    +
    +
    +
    +
    + +
    +

    Permissions

    +
    +
    + Filter permissions by:  + + +
    + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + +
    NameRolesCollectionPathMethodParams
    {{p.name}}{{displayRoles(p.roles)}}{{p.collectionNames}}{{displayList(p.paths)}}{{displayList(p.method)}}{{displayParams(p.params)}}
    +
    +
    + + + + + + +
    {{w}}
    +
    +
    +
    +
    +
    diff --git a/KeywordSearch/solr/server/start.jar b/KeywordSearch/solr/server/start.jar index 49aa128dd7..71bf9e91dd 100755 Binary files a/KeywordSearch/solr/server/start.jar and b/KeywordSearch/solr/server/start.jar differ diff --git a/NEWS.txt b/NEWS.txt index 0a09f7cffb..a675c6fb05 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -1,3 +1,10 @@ +---------------- VERSION 4.19.3 -------------- +Bug Fixes: +- Updates for log4j vulnerabilities. +-- Solr 8.11.0 Upgrade +-- Manual update of log4j to 2.16.0 +-- NOTE: This installer was created with some manual work because Solr 8.11.1 was not on maven at the time of building. + ---------------- VERSION 4.19.2 -------------- GUI Updates: - Special handling of Interesting Files and Interesting Results analysis results was removed from the tree and they are now shown as individual nodes. diff --git a/nbproject/project.properties b/nbproject/project.properties index 872c92042a..85be6e34cf 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -4,7 +4,7 @@ app.title=Autopsy ### lowercase version of above app.name=${branding.token} ### if left unset, version will default to today's date -app.version=4.19.2 +app.version=4.19.3 ### build.type must be one of: DEVELOPMENT, RELEASE #build.type=RELEASE build.type=DEVELOPMENT