| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.chemistry.opencmis.workbench; |
| |
| import static org.apache.chemistry.opencmis.commons.impl.CollectionsHelper.isNotEmpty; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Component; |
| import java.awt.Cursor; |
| import java.awt.Dimension; |
| import java.awt.FlowLayout; |
| import java.awt.Toolkit; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.GregorianCalendar; |
| import java.util.Map; |
| |
| import javax.swing.Icon; |
| import javax.swing.JButton; |
| import javax.swing.JComponent; |
| import javax.swing.JFrame; |
| import javax.swing.JPanel; |
| import javax.swing.JScrollPane; |
| import javax.swing.JTable; |
| import javax.swing.JTree; |
| import javax.swing.WindowConstants; |
| import javax.swing.tree.DefaultMutableTreeNode; |
| import javax.swing.tree.DefaultTreeCellRenderer; |
| import javax.swing.tree.DefaultTreeModel; |
| import javax.swing.tree.TreeSelectionModel; |
| |
| import org.apache.chemistry.opencmis.client.api.Session; |
| import org.apache.chemistry.opencmis.commons.data.AclCapabilities; |
| import org.apache.chemistry.opencmis.commons.data.ExtensionFeature; |
| import org.apache.chemistry.opencmis.commons.data.PermissionMapping; |
| import org.apache.chemistry.opencmis.commons.data.RepositoryCapabilities; |
| import org.apache.chemistry.opencmis.commons.data.RepositoryInfo; |
| import org.apache.chemistry.opencmis.commons.definitions.PermissionDefinition; |
| import org.apache.chemistry.opencmis.commons.enums.BaseTypeId; |
| import org.apache.chemistry.opencmis.commons.enums.PropertyType; |
| import org.apache.chemistry.opencmis.workbench.icons.ExtensionIcon; |
| import org.apache.chemistry.opencmis.workbench.model.ClientModel; |
| import org.apache.chemistry.opencmis.workbench.swing.ExtensionsTree; |
| import org.apache.chemistry.opencmis.workbench.swing.InfoPanel; |
| |
| public class RepositoryInfoFrame extends JFrame { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private static final String WINDOW_TITLE = "CMIS Repository Info"; |
| |
| private final ClientModel model; |
| private JComponent infoPanel; |
| |
| public RepositoryInfoFrame(ClientModel model) { |
| super(); |
| |
| this.model = model; |
| createGUI(); |
| } |
| |
| private void createGUI() { |
| setTitle(WINDOW_TITLE + " - " + model.getRepositoryName()); |
| setIconImages(ClientHelper.getCmisIconImages()); |
| |
| Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
| setPreferredSize(new Dimension((int) (screenSize.getWidth() / 2.5), (int) (screenSize.getHeight() / 1.5))); |
| setMinimumSize(new Dimension(200, 60)); |
| |
| setLayout(new BorderLayout()); |
| |
| RepositoryInfo repInfo = null; |
| try { |
| repInfo = model.getRepositoryInfo(); |
| } catch (Exception e) { |
| ClientHelper.showError(this, e); |
| dispose(); |
| return; |
| } |
| |
| infoPanel = new JScrollPane(new RepositoryInfoPanel(model, repInfo, -1)); |
| add(infoPanel, BorderLayout.CENTER); |
| |
| final JPanel inputPanel = new JPanel(new FlowLayout()); |
| add(inputPanel, BorderLayout.PAGE_END); |
| |
| JButton reloadButton = new JButton("Reload"); |
| reloadButton.addActionListener(new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| try { |
| setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); |
| |
| Session session = model.getClientSession().getSession(); |
| String repId = session.getRepositoryInfo().getId(); |
| RepositoryInfo repInfo = session.getBinding().getRepositoryService().getRepositoryInfo(repId, null); |
| |
| remove(infoPanel); |
| infoPanel = new JScrollPane(new RepositoryInfoPanel(model, repInfo, System.currentTimeMillis())); |
| add(infoPanel, BorderLayout.CENTER); |
| |
| validate(); |
| } finally { |
| setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); |
| } |
| } |
| }); |
| inputPanel.add(reloadButton, BorderLayout.LINE_END); |
| |
| getRootPane().setDefaultButton(reloadButton); |
| |
| ClientHelper.installEscapeBinding(this, getRootPane(), true); |
| |
| setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); |
| pack(); |
| |
| setLocationRelativeTo(null); |
| setVisible(true); |
| } |
| |
| static class RepositoryInfoPanel extends InfoPanel { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private final RepositoryInfo repInfo; |
| private final GregorianCalendar lastUpdate; |
| |
| public RepositoryInfoPanel(ClientModel model, RepositoryInfo repInfo, long lastUpdate) { |
| super(model); |
| |
| this.repInfo = repInfo; |
| if (lastUpdate >= 0) { |
| this.lastUpdate = new GregorianCalendar(); |
| this.lastUpdate.setTimeInMillis(lastUpdate); |
| } else { |
| this.lastUpdate = null; |
| } |
| createGUI(); |
| } |
| |
| private void createGUI() { |
| setupGUI(); |
| |
| addLine("Name:", true).setText(repInfo.getName()); |
| addSeparator(); |
| addLine("Id:").setText(repInfo.getId()); |
| addLine("Description:").setText(repInfo.getDescription()); |
| addLine("Vendor:").setText(repInfo.getVendorName()); |
| addLine("Product:").setText(repInfo.getProductName() + " " + repInfo.getProductVersion()); |
| addLine("CMIS Version:").setText(repInfo.getCmisVersionSupported()); |
| addId("Root folder Id:").setText(repInfo.getRootFolderId()); |
| addLine("Latest change token:").setText(repInfo.getLatestChangeLogToken()); |
| addLink("Thin client URI:").setText(repInfo.getThinClientUri()); |
| addLine("Principal id anonymous:").setText(repInfo.getPrincipalIdAnonymous()); |
| addLine("Principal id anyone:").setText(repInfo.getPrincipalIdAnyone()); |
| addYesNoLabel("Changes incomplete:").setValue(is(repInfo.getChangesIncomplete())); |
| |
| StringBuilder sb = new StringBuilder(64); |
| if (repInfo.getChangesOnType() != null) { |
| for (BaseTypeId bt : repInfo.getChangesOnType()) { |
| appendToString(sb, bt.value()); |
| } |
| } |
| addLine("Changes on type:").setText(sb.toString()); |
| |
| if (repInfo.getCapabilities() != null) { |
| RepositoryCapabilities cap = repInfo.getCapabilities(); |
| |
| addSeparator(); |
| addLine("Capabilities:", true).setText(""); |
| |
| addYesNoLabel("Get descendants supported:").setValue(is(cap.isGetDescendantsSupported())); |
| addYesNoLabel("Get folder tree supported:").setValue(is(cap.isGetFolderTreeSupported())); |
| addYesNoLabel("Unfiling supported:").setValue(is(cap.isUnfilingSupported())); |
| addYesNoLabel("Multifiling supported:").setValue(is(cap.isMultifilingSupported())); |
| addYesNoLabel("Version specific filing supported:") |
| .setValue(is(cap.isVersionSpecificFilingSupported())); |
| addLine("Order by:").setText(str(cap.getOrderByCapability())); |
| addLine("Query:").setText(str(cap.getQueryCapability())); |
| addLine("Joins:").setText(str(cap.getJoinCapability())); |
| addYesNoLabel("All versions searchable:").setValue(is(cap.isAllVersionsSearchableSupported())); |
| addYesNoLabel("PWC searchable:").setValue(is(cap.isPwcSearchableSupported())); |
| addYesNoLabel("PWC updatable:").setValue(is(cap.isPwcUpdatableSupported())); |
| addLine("Content stream updates:").setText(str(cap.getContentStreamUpdatesCapability())); |
| addLine("Renditions:").setText(str(cap.getRenditionsCapability())); |
| addLine("Changes:").setText(str(cap.getChangesCapability())); |
| addLine("ACLs:").setText(str(cap.getAclCapability())); |
| |
| sb = new StringBuilder(128); |
| if (cap.getNewTypeSettableAttributes() != null) { |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetId())) { |
| appendToString(sb, "id"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetLocalName())) { |
| appendToString(sb, "localName"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetLocalNamespace())) { |
| appendToString(sb, "localNamespace"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetDisplayName())) { |
| appendToString(sb, "displayName"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetQueryName())) { |
| appendToString(sb, "queryName"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetDescription())) { |
| appendToString(sb, "description"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetCreatable())) { |
| appendToString(sb, "creatable"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetFileable())) { |
| appendToString(sb, "fileable"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetQueryable())) { |
| appendToString(sb, "queryable"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetFulltextIndexed())) { |
| appendToString(sb, "fulltextIndexed"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetIncludedInSupertypeQuery())) { |
| appendToString(sb, "includedInSupertypeQuery"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetControllablePolicy())) { |
| appendToString(sb, "controllablePolicy"); |
| } |
| |
| if (Boolean.TRUE.equals(cap.getNewTypeSettableAttributes().canSetControllableAcl())) { |
| appendToString(sb, "controllableACL"); |
| } |
| } |
| |
| addLine("New type settable attributes:").setText(sb.toString()); |
| |
| sb = new StringBuilder(64); |
| if (cap.getCreatablePropertyTypes() != null && cap.getCreatablePropertyTypes().canCreate() != null) { |
| for (PropertyType pt : cap.getCreatablePropertyTypes().canCreate()) { |
| appendToString(sb, pt.value()); |
| } |
| } |
| |
| addLine("Creatable property types:").setText(sb.toString()); |
| } |
| |
| if (repInfo.getAclCapabilities() != null) { |
| AclCapabilities cap = repInfo.getAclCapabilities(); |
| |
| addSeparator(); |
| addLine("ACL Capabilities:", true).setText(""); |
| |
| addLine("Supported permissions:").setText(str(cap.getSupportedPermissions())); |
| addLine("ACL propagation:").setText(str(cap.getAclPropagation())); |
| |
| if (cap.getPermissions() != null) { |
| String[][] data = new String[cap.getPermissions().size()][2]; |
| |
| int i = 0; |
| for (PermissionDefinition pd : cap.getPermissions()) { |
| data[i][0] = pd.getId(); |
| data[i][1] = pd.getDescription(); |
| i++; |
| } |
| |
| JTable permTable = new JTable(data, new String[] { "Permission", "Description" }); |
| permTable.setFillsViewportHeight(true); |
| permTable.setRowHeight((int) (getFontMetrics(getFont()).getHeight() * 1.1)); |
| addComponent("Permissions:", createScrollePane(permTable)); |
| } |
| |
| if (cap.getPermissionMapping() != null) { |
| String[][] data = new String[cap.getPermissionMapping().size()][2]; |
| |
| int i = 0; |
| for (PermissionMapping pm : cap.getPermissionMapping().values()) { |
| data[i][0] = pm.getKey(); |
| data[i][1] = (pm.getPermissions() == null ? "" : pm.getPermissions().toString()); |
| i++; |
| } |
| |
| JTable permMapTable = new JTable(data, new String[] { "Key", "Permissions" }); |
| permMapTable.setFillsViewportHeight(true); |
| permMapTable.setRowHeight((int) (getFontMetrics(getFont()).getHeight() * 1.1)); |
| addComponent("Permission mapping:", createScrollePane(permMapTable)); |
| } |
| } |
| |
| if (isNotEmpty(repInfo.getExtensionFeatures())) { |
| JTree extensionFeaturesTree = new JTree(); |
| extensionFeaturesTree.setRootVisible(false); |
| extensionFeaturesTree.setCellRenderer(new ExtensionFeatureCellRenderer()); |
| extensionFeaturesTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); |
| |
| DefaultMutableTreeNode extFeatRootNode = new DefaultMutableTreeNode("Extensions"); |
| |
| for (ExtensionFeature ef : repInfo.getExtensionFeatures()) { |
| DefaultMutableTreeNode efNode = new DefaultMutableTreeNode(ef); |
| extFeatRootNode.add(efNode); |
| |
| if (ef.getCommonName() != null) { |
| efNode.add(new DefaultMutableTreeNode("Common Name: " + ef.getCommonName())); |
| } |
| |
| if (ef.getVersionLabel() != null) { |
| efNode.add(new DefaultMutableTreeNode("Version Label: " + ef.getVersionLabel())); |
| } |
| |
| if (ef.getDescription() != null) { |
| efNode.add(new DefaultMutableTreeNode("Description: " + ef.getDescription())); |
| } |
| |
| if (ef.getUrl() != null) { |
| efNode.add(new DefaultMutableTreeNode("URL: " + ef.getUrl())); |
| } |
| |
| if (isNotEmpty(ef.getFeatureData())) { |
| DefaultMutableTreeNode dataNode = new DefaultMutableTreeNode("Feature Data"); |
| efNode.add(dataNode); |
| |
| for (Map.Entry<String, String> e : ef.getFeatureData().entrySet()) { |
| dataNode.add(new DefaultMutableTreeNode(e.getKey() + ": " + e.getValue())); |
| } |
| } |
| } |
| |
| extensionFeaturesTree.setModel(new DefaultTreeModel(extFeatRootNode)); |
| |
| addComponent("Extension Features:", createScrollePane(extensionFeaturesTree)); |
| } |
| |
| if (isNotEmpty(repInfo.getExtensions())) { |
| addComponent("Extensions:", createScrollePane(new ExtensionsTree(repInfo.getExtensions()))); |
| } |
| |
| addSeparator(); |
| addLine("Last update:").setText(lastUpdate != null ? ClientHelper.getDateString(lastUpdate) : "(session)"); |
| |
| regenerateGUI(); |
| } |
| |
| private JScrollPane createScrollePane(Component comp) { |
| JScrollPane pane = new JScrollPane(comp); |
| pane.setPreferredSize(new Dimension(pane.getPreferredSize().width, WorkbenchScale.scaleInt(200))); |
| |
| return pane; |
| } |
| |
| private void appendToString(StringBuilder sb, String str) { |
| if (sb.length() > 0) { |
| sb.append(", "); |
| } |
| |
| sb.append(str); |
| } |
| |
| private boolean is(Boolean b) { |
| if (b == null) { |
| return false; |
| } |
| |
| return b.booleanValue(); |
| } |
| |
| private String str(Object o) { |
| if (o == null) { |
| return "?"; |
| } |
| |
| return o.toString(); |
| } |
| |
| static class ExtensionFeatureCellRenderer extends DefaultTreeCellRenderer { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private static final Icon EXTENSION_ICON = new ExtensionIcon(ClientHelper.OBJECT_ICON_SIZE, |
| ClientHelper.OBJECT_ICON_SIZE); |
| |
| @Override |
| public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, |
| boolean leaf, int row, boolean hasFocus) { |
| Component comp = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); |
| |
| Object node = ((DefaultMutableTreeNode) value).getUserObject(); |
| if (node instanceof ExtensionFeature) { |
| setText(((ExtensionFeature) node).getId()); |
| setIcon(EXTENSION_ICON); |
| } else { |
| setIcon(null); |
| } |
| |
| return comp; |
| } |
| } |
| } |
| } |