diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenue.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenue.java
index baabeaf81b..14000f7f78 100644
--- a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenue.java
+++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenue.java
@@ -40,6 +40,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* Jan 28, 2014 2698 bclement removed getInfo, added methods to replace
* Jan 30, 2014 2698 bclement changed UserId to VenueParticipant
* Mar 06, 2014 2751 bclement added getParticipantUserid()
+ * Jan 09, 2015 3709 bclement added isPersistent()
*
*
*
@@ -91,4 +92,10 @@ public interface IVenue {
*/
public UserId getParticipantUserid(VenueParticipant participant);
+ /**
+ * @return true if this is a room that exists on the server even when there
+ * are no participants
+ */
+ public boolean isPersistent();
+
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/Venue.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/Venue.java
index db19abea4d..d7648c5d42 100644
--- a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/Venue.java
+++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/Venue.java
@@ -34,10 +34,12 @@ import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.Affiliate;
import org.jivesoftware.smackx.muc.MultiUserChat;
+import org.jivesoftware.smackx.muc.RoomInfo;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenue;
+import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
@@ -59,6 +61,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* Mar 05, 2014 2798 mpduff Get Presence from MUC.
* Mar 06, 2014 2751 bclement added getParticipantUserid()
* Mar 07, 2014 2848 bclement added hasOtherParticipants()
+ * Jan 09, 2015 3709 bclement added isPersistent()
*
*
*
@@ -195,4 +198,21 @@ public class Venue implements IVenue {
return getParticipantCount() > 1;
}
+ @Override
+ public boolean isPersistent() {
+ boolean rval = false;
+ CollaborationConnection connection = CollaborationConnection
+ .getConnection();
+ XMPPConnection xmppConn = connection.getXmppConnection();
+ try {
+ RoomInfo roomInfo = MultiUserChat.getRoomInfo(xmppConn,
+ muc.getRoom());
+ rval = roomInfo.isPersistent();
+ } catch (XMPPException e) {
+ log.error("Unable to determine if room " + this.getId()
+ + " is persistent", e);
+ }
+ return rval;
+ }
+
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/VenueSession.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/VenueSession.java
index edecaf14ad..77419b9de3 100644
--- a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/VenueSession.java
+++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/VenueSession.java
@@ -113,7 +113,8 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
* Apr 29, 2014 3061 bclement moved invite payload to shared display session
* May 09, 2014 3107 bclement removed catch from isRoomOwner() so callers know about errors
* Jun 16, 2014 3288 bclement changed String venueName to VenueId venueId, added createVenueId()
- * Oct 08, 2014 3705 bclement aded getVenueId()
+ * Oct 08, 2014 3705 bclement added getVenueId()
+ * Jan 12, 2015 3709 bclement fixed rare invite bug
*
*
*
@@ -247,7 +248,11 @@ public class VenueSession extends BaseSession implements IVenueSession {
protected Message createInviteMessage(UserId id, VenueInvite invite) {
Message msg = new Message();
msg.setType(Type.normal);
- msg.setBody(invite.getMessage());
+ /*
+ * don't set a body on the message. smack will add a packet extension on
+ * it that will have the actual invite. openfire gets confused if there
+ * is both a body and an extension and drops the invite on the floor.
+ */
return msg;
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationGroupView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationGroupView.java
index dd1b19812c..badd7add3e 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationGroupView.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationGroupView.java
@@ -123,6 +123,7 @@ import com.raytheon.uf.viz.collaboration.ui.actions.RemoveFromRosterAction;
import com.raytheon.uf.viz.collaboration.ui.actions.SendSubReqAction;
import com.raytheon.uf.viz.collaboration.ui.actions.ShowVenueAction;
import com.raytheon.uf.viz.collaboration.ui.actions.UserSearchAction;
+import com.raytheon.uf.viz.collaboration.ui.colors.UserColorConfigManager;
import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper;
import com.raytheon.uf.viz.collaboration.ui.data.CollaborationGroupContainer;
import com.raytheon.uf.viz.collaboration.ui.data.PublicRoomContainer;
@@ -168,6 +169,7 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
* Nov 14, 2014 3709 mapeters Removed change background/foreground color actions from menu.
* Dec 08, 2014 3709 mapeters Added MB3 change user text color actions to contacts list.
* Dec 12, 2014 3709 mapeters Store {@link ChangeTextColorAction}s in map, dispose them.
+ * Jan 09, 2015 3709 bclement color config manager API changes
*
*
*
@@ -448,7 +450,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
if (o instanceof SessionGroupContainer) {
manager.add(createSessionAction);
return;
- } else if (o instanceof PublicRoomContainer){
+ } else if (o instanceof PublicRoomContainer) {
manager.add(roomSearchAction);
return;
} else if (o instanceof IVenueSession) {
@@ -476,14 +478,15 @@ public class CollaborationGroupView extends CaveFloatingView implements
}
manager.add(new AddNotifierAction(this));
manager.add(new Separator());
- String name = user.getName();
- ChangeTextColorAction userColorAction = userColorActions.get(name);
+ String colorActionKey = user.getFQName();
+ ChangeTextColorAction userColorAction = userColorActions
+ .get(colorActionKey);
if (userColorAction == null) {
userColorAction = ChangeTextColorAction
- .createChangeUserTextColorAction(name, false, false,
+ .createChangeUserTextColorAction(user, false, false,
new RGB(0, 0, 255),
- new UserColorConfigManager());
- userColorActions.put(name, userColorAction);
+ UserColorConfigManager.getInstance());
+ userColorActions.put(colorActionKey, userColorAction);
}
manager.add(userColorAction);
} else if (o instanceof UserId) {
@@ -494,15 +497,15 @@ public class CollaborationGroupView extends CaveFloatingView implements
UserId me = connection.getUser();
if (me.isSameUser(user)) {
createMenu(manager);
- String name = user.getName();
+ String colorActionKey = user.getFQName();
ChangeTextColorAction userColorAction = userColorActions
- .get(name);
+ .get(colorActionKey);
if (userColorAction == null) {
userColorAction = ChangeTextColorAction
- .createChangeUserTextColorAction(name, true, true,
+ .createChangeUserTextColorAction(user, true, true,
new RGB(0, 0, 255),
- new UserColorConfigManager());
- userColorActions.put(name, userColorAction);
+ UserColorConfigManager.getInstance());
+ userColorActions.put(colorActionKey, userColorAction);
}
manager.insertBefore("afterFont", userColorAction);
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeTextColorAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeTextColorAction.java
index afb065ff0f..2af01c6829 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeTextColorAction.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeTextColorAction.java
@@ -32,12 +32,12 @@ import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import com.google.common.eventbus.Subscribe;
+import com.raytheon.uf.viz.collaboration.comm.identity.user.IUser;
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
-import com.raytheon.uf.viz.collaboration.ui.AbstractColorConfigManager;
-import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
-import com.raytheon.uf.viz.collaboration.ui.FeedColorConfigManager;
-import com.raytheon.uf.viz.collaboration.ui.ForegroundBackgroundColorDlg;
-import com.raytheon.uf.viz.collaboration.ui.UserColorConfigManager;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
+import com.raytheon.uf.viz.collaboration.ui.colors.FeedColorConfigManager;
+import com.raytheon.uf.viz.collaboration.ui.colors.ForegroundBackgroundColorDlg;
+import com.raytheon.uf.viz.collaboration.ui.colors.IColorConfigManager;
import com.raytheon.viz.ui.dialogs.ICloseCallback;
/**
@@ -50,12 +50,13 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
- * 12/02/14 3709 mapeters Initial creation.
- * 12/09/14 3709 mapeters Uses {@link ForegroundBackgroundColorDlg}, renamed from
+ * Dec 02, 2014 3709 mapeters Initial creation.
+ * Dec 09, 2014 3709 mapeters Uses {@link ForegroundBackgroundColorDlg}, renamed from
* ChangeUserColorAction, support both user and site colors.
- * 12/12/14 3709 mapeters Use static methods to call constructor, icon displays
+ * Dec 12, 2014 3709 mapeters Use static methods to call constructor, icon displays
* current foreground and background colors.
- * 01/05/15 3709 mapeters Added getTextColors(), added me param to createChangeUserTextColorAction().
+ * Jan 05, 2015 3709 mapeters Added getTextColors(), added me param to createChangeUserTextColorAction().
+ * Jan 09, 2015 3709 bclement color change manager API changes
*
*
*
@@ -68,7 +69,7 @@ public class ChangeTextColorAction extends Action {
private RGB defaultForeground;
- private AbstractColorConfigManager colorConfigManager;
+ private IColorConfigManager colorConfigManager;
private Image icon;
@@ -88,20 +89,21 @@ public class ChangeTextColorAction extends Action {
* @return
*/
public static ChangeTextColorAction createChangeUserTextColorAction(
- String user, boolean me, boolean displayName,
- RGB defaultForeground, UserColorConfigManager colorConfigManager) {
+ IUser user, boolean me, boolean displayName,
+ RGB defaultForeground, IColorConfigManager colorConfigManager) {
+ String name = user.getName();
String text = "Change ";
if (displayName) {
- text += me ? "Your" : (user + "'s");
+ text += me ? "Your" : (name + "'s");
} else {
text += "User";
}
text += " Text Colors...";
- return new ChangeTextColorAction(text, user, defaultForeground,
- colorConfigManager);
+ return new ChangeTextColorAction(text, user.getFQName(),
+ defaultForeground, colorConfigManager);
}
-
+
/**
* Create and return new action for changing site colors.
*
@@ -121,7 +123,7 @@ public class ChangeTextColorAction extends Action {
}
private ChangeTextColorAction(String text, String key,
- RGB defaultForeground, AbstractColorConfigManager colorConfigManager) {
+ RGB defaultForeground, IColorConfigManager colorConfigManager) {
super(text);
this.key = key;
this.defaultForeground = defaultForeground;
@@ -137,7 +139,8 @@ public class ChangeTextColorAction extends Action {
public void run() {
RGB[] colors = getTextColors();
ForegroundBackgroundColorDlg dialog = new ForegroundBackgroundColorDlg(
- Display.getCurrent().getActiveShell(), colors[0], colors[1]);
+ Display.getCurrent().getActiveShell(),
+ colorConfigManager.getDescription(key), colors[0], colors[1]);
dialog.setCloseCallback(new ICloseCallback() {
@@ -238,4 +241,5 @@ public class ChangeTextColorAction extends Action {
icon.dispose();
}
}
+
}
\ No newline at end of file
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ColorInfoMap.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ColorInfoMap.java
similarity index 98%
rename from cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ColorInfoMap.java
rename to cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ColorInfoMap.java
index 9fca15f040..d62a28352c 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ColorInfoMap.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ColorInfoMap.java
@@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.uf.viz.collaboration.ui;
+package com.raytheon.uf.viz.collaboration.ui.colors;
import java.util.Map;
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/FeedColorConfigManager.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/FeedColorConfigManager.java
similarity index 68%
rename from cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/FeedColorConfigManager.java
rename to cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/FeedColorConfigManager.java
index 276427ddce..5980631220 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/FeedColorConfigManager.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/FeedColorConfigManager.java
@@ -17,12 +17,12 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.uf.viz.collaboration.ui;
+package com.raytheon.uf.viz.collaboration.ui.colors;
import org.eclipse.swt.graphics.RGB;
import com.raytheon.uf.common.localization.IPathManager;
-import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
/**
* Configuration manager for reading/writing colors for each site to/from a
@@ -35,21 +35,32 @@ import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Oct 10, 2014 3708 bclement Moved color methods from SiteConfigurationManager
- * Nov 26, 2014 3709 mapeters Abstracted out code to {@link AbstractColorConfigManager},
+ * Nov 26, 2014 3709 mapeters Abstracted out code to {@link PersistentColorConfigManager},
* renamed from SiteColorConfigManager.
* Dec 08, 2014 3709 mapeters Set foreground and background colors together.
+ * Jan 09, 2015 3709 bclement made into a true singleton, moved colorInfoMap to super
*
*
*
* @author bclement
* @version 1.0
*/
-public class FeedColorConfigManager extends AbstractColorConfigManager {
+public class FeedColorConfigManager extends PersistentColorConfigManager {
- private static final String FILE_PATH = "collaboration"
+ private static final String FILE_PATH = CONFIG_DIR_NAME
+ IPathManager.SEPARATOR + "siteColorInfo.xml";
- private static ColorInfoMap colorInfoMap;
+ private static FeedColorConfigManager instance;
+
+ public static synchronized FeedColorConfigManager getInstance() {
+ if (instance == null) {
+ instance = new FeedColorConfigManager();
+ }
+ return instance;
+ }
+
+ protected FeedColorConfigManager() {
+ }
/**
* Set and store the given colors for the given site.
@@ -75,13 +86,16 @@ public class FeedColorConfigManager extends AbstractColorConfigManager {
return super.getColor(site, FILE_PATH);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.raytheon.uf.viz.collaboration.ui.colors.IColorConfigManager#
+ * getDescription()
+ */
@Override
- protected ColorInfoMap getColorInfoMap() {
- return colorInfoMap;
+ public String getDescription(String key) {
+ return "Color changes will apply to all users from site " + key
+ + " in the feed room.";
}
- @Override
- protected void setColorInfoMap(ColorInfoMap colorInfoMap) {
- FeedColorConfigManager.colorInfoMap = colorInfoMap;
- }
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ForegroundBackgroundColorDlg.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ForegroundBackgroundColorDlg.java
new file mode 100644
index 0000000000..5eb24e9020
--- /dev/null
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ForegroundBackgroundColorDlg.java
@@ -0,0 +1,177 @@
+/**
+ * This software was developed and / or modified by Raytheon Company,
+ * pursuant to Contract DG133W-05-CQ-1067 with the US Government.
+ *
+ * U.S. EXPORT CONTROLLED TECHNICAL DATA
+ * This software product contains export-restricted data whose
+ * export/transfer/disclosure is restricted by U.S. law. Dissemination
+ * to non-U.S. persons whether in the United States or abroad requires
+ * an export license or other authorization.
+ *
+ * Contractor Name: Raytheon Company
+ * Contractor Address: 6825 Pine Street, Suite 340
+ * Mail Stop B8
+ * Omaha, NE 68106
+ * 402.291.0100
+ *
+ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
+ * further licensing information.
+ **/
+package com.raytheon.uf.viz.collaboration.ui.colors;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A dialog that displays a label with settable foreground and background colors
+ * using a color control.
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 04, 2014 3709 lvenable Initial creation
+ * Jan 09, 2015 3709 bclement moved primary logic to new super class
+ *
+ *
+ *
+ * @author lvenable
+ * @version 1.0
+ */
+public class ForegroundBackgroundColorDlg extends ForegroundColorDlg {
+
+ /** Background color. */
+ private Color backgroundClr = null;
+
+ private Button foregroundRdo;
+
+ /**
+ * Constructor.
+ *
+ * @param parentShell
+ * Parent shell.
+ */
+ public ForegroundBackgroundColorDlg(Shell parentShell, String description) {
+ this(parentShell, description, null, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param parentShell
+ * Parent shell.
+ * @param fgRGB
+ * Foreground RGB.
+ * @param bgRGB
+ * Background RGB.
+ */
+ public ForegroundBackgroundColorDlg(Shell parentShell, String description,
+ RGB fgRGB, RGB bgRGB) {
+ super(parentShell, description, fgRGB);
+ setText("Foreground/Background Color Chooser");
+
+ /*
+ * If the background RGB is null then set it to a white color.
+ */
+ if (bgRGB == null) {
+ backgroundClr = new Color(parentShell.getDisplay(), new RGB(255,
+ 255, 255));
+ } else {
+ backgroundClr = new Color(parentShell.getDisplay(), bgRGB);
+ }
+ }
+
+
+ @Override
+ protected void disposed() {
+ super.disposed();
+
+ if (backgroundClr != null) {
+ backgroundClr.dispose();
+ }
+ }
+
+ @Override
+ protected void createColorControls() {
+ Composite colorControlComp = new Composite(shell, SWT.NONE);
+ colorControlComp.setLayout(new GridLayout(3, false));
+ colorControlComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT,
+ true, false));
+
+ /*
+ * Foreground/background radio buttons.
+ */
+ foregroundRdo = new Button(colorControlComp, SWT.RADIO);
+ foregroundRdo.setText("Foreground Color");
+ foregroundRdo.setSelection(true);
+ foregroundRdo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ colorWheelComp.setColor(foregroundClr.getRGB());
+ }
+ });
+
+ GridData gd = new GridData();
+ gd.horizontalIndent = 13;
+ Button backgroundRdo = new Button(colorControlComp, SWT.RADIO);
+ backgroundRdo.setText("Background Color");
+ backgroundRdo.setLayoutData(gd);
+ backgroundRdo.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ colorWheelComp.setColor(backgroundClr.getRGB());
+ }
+ });
+
+ /*
+ * Label displaying the foreground/background colors.
+ */
+ gd = new GridData();
+ gd.horizontalIndent = 13;
+ previewLabel = new Label(colorControlComp, SWT.BORDER);
+ FontData fd = previewLabel.getFont().getFontData()[0];
+ fd.setHeight(16);
+ fd.setStyle(SWT.BOLD);
+ labelFont = new Font(getDisplay(), fd);
+ previewLabel.setFont(labelFont);
+ previewLabel.setText(" Sample Text ");
+ previewLabel.setLayoutData(gd);
+
+ previewLabel.setForeground(foregroundClr);
+ previewLabel.setBackground(backgroundClr);
+ }
+
+ @Override
+ protected void collectReturnValue() {
+ RGB[] rgbArray = new RGB[] { foregroundClr.getRGB(),
+ backgroundClr.getRGB() };
+ setReturnValue(rgbArray);
+ }
+
+ @Override
+ public void colorChange(RGB rgb, String colorWheelTitle) {
+ if (foregroundRdo.getSelection()) {
+ foregroundClr.dispose();
+ foregroundClr = new Color(getDisplay(), rgb);
+ previewLabel.setForeground(foregroundClr);
+ } else {
+ backgroundClr.dispose();
+ backgroundClr = new Color(getDisplay(), rgb);
+ previewLabel.setBackground(backgroundClr);
+ }
+ }
+
+}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ForegroundBackgroundColorDlg.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ForegroundColorDlg.java
similarity index 59%
rename from cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ForegroundBackgroundColorDlg.java
rename to cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ForegroundColorDlg.java
index 006f66942b..f6d10b24ce 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ForegroundBackgroundColorDlg.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/ForegroundColorDlg.java
@@ -17,7 +17,7 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.uf.viz.collaboration.ui;
+package com.raytheon.uf.viz.collaboration.ui.colors;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
@@ -39,8 +39,8 @@ import com.raytheon.viz.ui.dialogs.colordialog.ColorWheelComp;
import com.raytheon.viz.ui.dialogs.colordialog.IColorWheelChange;
/**
- * A dialog that displays a label with settable foreground and background colors
- * using a color control.
+ * A dialog that displays a label with settable foreground color using a color
+ * control.
*
*
*
@@ -48,32 +48,31 @@ import com.raytheon.viz.ui.dialogs.colordialog.IColorWheelChange;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
- * Dec 4, 2014 3709 lvenable Initial creation
+ * Jan 09, 2015 3709 bclement Initial creation, logic from ForegroundBackgroundColorDlg
*
*
*
- * @author lvenable
+ * @author bclement
* @version 1.0
*/
-public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
+public class ForegroundColorDlg extends CaveSWTDialog implements
IColorWheelChange {
/** Color wheel composite. */
- private ColorWheelComp colorWheelComp;
+ protected ColorWheelComp colorWheelComp;
/** Foreground color. */
- private Color foregroundClr = null;
+ protected Color foregroundClr = null;
- /** Background color. */
- private Color backgroundClr = null;
+ /** preview label control. */
+ protected Label previewLabel = null;
- /** Foreground/Background label control. */
- private Label fgbgLabel = null;
+ /** Font for the preview label. */
+ protected Font labelFont = null;
- /** Fond for the foreground/background label. */
- private Font labelFont = null;
+ protected final String description;
- private Button foregroundRdo;
+ protected Label descriptionLabel = null;
/**
* Constructor.
@@ -81,8 +80,8 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
* @param parentShell
* Parent shell.
*/
- public ForegroundBackgroundColorDlg(Shell parentShell) {
- this(parentShell, null, null);
+ public ForegroundColorDlg(Shell parentShell, String description) {
+ this(parentShell, description, null);
}
/**
@@ -92,14 +91,12 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
* Parent shell.
* @param fgRGB
* Foreground RGB.
- * @param bgRGB
- * Background RGB.
*/
- public ForegroundBackgroundColorDlg(Shell parentShell, RGB fgRGB, RGB bgRGB) {
+ public ForegroundColorDlg(Shell parentShell, String description, RGB fgRGB) {
super(parentShell, SWT.DIALOG_TRIM | SWT.MIN, CAVE.DO_NOT_BLOCK
| CAVE.PERSPECTIVE_INDEPENDENT);
- setText("Foreground/Background Color Chooser");
-
+ setText("Foreground Color Chooser");
+ this.description = description;
/*
* If the foreground RGB is null then set it to a blue color.
*/
@@ -109,16 +106,6 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
} else {
foregroundClr = new Color(parentShell.getDisplay(), fgRGB);
}
-
- /*
- * If the background RGB is null then set it to a white color.
- */
- if (bgRGB == null) {
- backgroundClr = new Color(parentShell.getDisplay(), new RGB(255,
- 255, 255));
- } else {
- backgroundClr = new Color(parentShell.getDisplay(), bgRGB);
- }
}
@Override
@@ -140,19 +127,21 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
foregroundClr.dispose();
}
- if (backgroundClr != null) {
- backgroundClr.dispose();
- }
-
if (labelFont != null) {
labelFont.dispose();
}
+ if (descriptionLabel != null) {
+ descriptionLabel.dispose();
+ }
}
@Override
protected void initializeComponents(Shell shell) {
createColorWheelControl();
createColorControls();
+ if (description != null && !description.isEmpty()) {
+ createDescriptionLabel();
+ }
addSeparator();
createBottomButtons();
@@ -162,7 +151,7 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
/**
* Create the color wheel controls.
*/
- private void createColorWheelControl() {
+ protected void createColorWheelControl() {
colorWheelComp = new ColorWheelComp(shell, this, " Color Chooser: ",
true);
}
@@ -170,59 +159,33 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
/**
* Create the color controls.
*/
- private void createColorControls() {
- Composite colorControlComp = new Composite(shell, SWT.NONE);
- colorControlComp.setLayout(new GridLayout(3, false));
- colorControlComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT,
- true, false));
-
- /*
- * Foreground/background radio buttons.
- */
- foregroundRdo = new Button(colorControlComp, SWT.RADIO);
- foregroundRdo.setText("Foreground Color");
- foregroundRdo.setSelection(true);
- foregroundRdo.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- colorWheelComp.setColor(foregroundClr.getRGB());
- }
- });
-
- GridData gd = new GridData();
- gd.horizontalIndent = 13;
- Button backgroundRdo = new Button(colorControlComp, SWT.RADIO);
- backgroundRdo.setText("Background Color");
- backgroundRdo.setLayoutData(gd);
- backgroundRdo.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- colorWheelComp.setColor(backgroundClr.getRGB());
- }
- });
-
- /*
- * Label displaying the foreground/background colors.
- */
- gd = new GridData();
- gd.horizontalIndent = 13;
- fgbgLabel = new Label(colorControlComp, SWT.BORDER);
- FontData fd = fgbgLabel.getFont().getFontData()[0];
+ protected void createColorControls() {
+ previewLabel = new Label(shell, SWT.BORDER);
+ FontData fd = previewLabel.getFont().getFontData()[0];
fd.setHeight(16);
fd.setStyle(SWT.BOLD);
labelFont = new Font(getDisplay(), fd);
- fgbgLabel.setFont(labelFont);
- fgbgLabel.setText(" Sample Text ");
- fgbgLabel.setLayoutData(gd);
+ previewLabel.setFont(labelFont);
+ previewLabel.setText(" Sample Text ");
+ previewLabel.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true,
+ true));
+ previewLabel.setForeground(foregroundClr);
+ }
- fgbgLabel.setForeground(foregroundClr);
- fgbgLabel.setBackground(backgroundClr);
+ /**
+ * Create a label that describes the scope of the color change.
+ */
+ protected void createDescriptionLabel() {
+ descriptionLabel = new Label(shell, SWT.CENTER);
+ descriptionLabel.setText(description);
+ descriptionLabel.setLayoutData(new GridData(SWT.CENTER, SWT.FILL, true,
+ true));
}
/**
* Create the bottom OK/Cancel buttons.
*/
- private void createBottomButtons() {
+ protected void createBottomButtons() {
Composite buttonComp = new Composite(shell, SWT.NONE);
buttonComp.setLayout(new GridLayout(2, false));
buttonComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true,
@@ -238,9 +201,7 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
okBtn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- RGB[] rgbArray = new RGB[] { foregroundClr.getRGB(),
- backgroundClr.getRGB() };
- setReturnValue(rgbArray);
+ collectReturnValue();
close();
}
});
@@ -259,10 +220,18 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
});
}
+ /**
+ * Collect the return value from fields. Called when user clicks the ok
+ * button.
+ */
+ protected void collectReturnValue() {
+ setReturnValue(foregroundClr.getRGB());
+ }
+
/**
* Add a separator line to the dialog.
*/
- private void addSeparator() {
+ protected void addSeparator() {
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
Label sepLbl = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
sepLbl.setLayoutData(gd);
@@ -277,15 +246,9 @@ public class ForegroundBackgroundColorDlg extends CaveSWTDialog implements
*/
@Override
public void colorChange(RGB rgb, String colorWheelTitle) {
- if (foregroundRdo.getSelection()) {
- foregroundClr.dispose();
- foregroundClr = new Color(getDisplay(), rgb);
- fgbgLabel.setForeground(foregroundClr);
- } else {
- backgroundClr.dispose();
- backgroundClr = new Color(getDisplay(), rgb);
- fgbgLabel.setBackground(backgroundClr);
- }
-
+ foregroundClr.dispose();
+ foregroundClr = new Color(getDisplay(), rgb);
+ previewLabel.setForeground(foregroundClr);
}
+
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/IColorConfigManager.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/IColorConfigManager.java
new file mode 100644
index 0000000000..a70d05989c
--- /dev/null
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/IColorConfigManager.java
@@ -0,0 +1,68 @@
+/**
+ * This software was developed and / or modified by Raytheon Company,
+ * pursuant to Contract DG133W-05-CQ-1067 with the US Government.
+ *
+ * U.S. EXPORT CONTROLLED TECHNICAL DATA
+ * This software product contains export-restricted data whose
+ * export/transfer/disclosure is restricted by U.S. law. Dissemination
+ * to non-U.S. persons whether in the United States or abroad requires
+ * an export license or other authorization.
+ *
+ * Contractor Name: Raytheon Company
+ * Contractor Address: 6825 Pine Street, Suite 340
+ * Mail Stop B8
+ * Omaha, NE 68106
+ * 402.291.0100
+ *
+ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
+ * further licensing information.
+ **/
+package com.raytheon.uf.viz.collaboration.ui.colors;
+
+import org.eclipse.swt.graphics.RGB;
+
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
+
+/**
+ * Interface for color configuration managers to keep track of custom color
+ * settings for users. Colors are tracked by a string key which could be the
+ * user name or attribute (eg site name).
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 08, 2015 3709 bclement Initial creation
+ *
+ *
+ *
+ * @author bclement
+ * @version 1.0
+ */
+public interface IColorConfigManager {
+
+ /**
+ * Set display colors
+ *
+ * @param key
+ * @param foreground
+ * @param background
+ */
+ public void setColors(String key, RGB foreground, RGB background);
+
+ /**
+ * Get display colors
+ *
+ * @param key
+ * @return
+ */
+ public ColorInfo getColor(String key);
+
+ /**
+ * @return human readable description of color management
+ */
+ public String getDescription(String key);
+
+}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/AbstractColorConfigManager.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/PersistentColorConfigManager.java
similarity index 85%
rename from cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/AbstractColorConfigManager.java
rename to cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/PersistentColorConfigManager.java
index 64b8beac91..834607c77c 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/AbstractColorConfigManager.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/PersistentColorConfigManager.java
@@ -1,4 +1,4 @@
-package com.raytheon.uf.viz.collaboration.ui;
+package com.raytheon.uf.viz.collaboration.ui.colors;
import java.util.HashMap;
import java.util.Map;
@@ -14,7 +14,8 @@ import com.raytheon.uf.common.localization.PathManager;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SingleTypeJAXBManager;
-import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
+import com.raytheon.uf.viz.collaboration.ui.Activator;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
/**
* Abstract class for collaboration chat coloring configuration managers
@@ -27,17 +28,24 @@ import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
* ------------ ---------- ----------- --------------------------
* Nov 13, 2014 3709 mapeters Initial creation.
* Dec 09, 2014 3709 mapeters setColors() sets foreground and background together.
+ * Jan 09, 2015 3709 bclement renamed from AbstractColorConfigManager
+ * moved colorInfoMap from subclasses to here
*
*
*
* @author mapeters
* @version 1.0
*/
-public abstract class AbstractColorConfigManager {
+public abstract class PersistentColorConfigManager implements
+ IColorConfigManager {
+
+ protected static final String CONFIG_DIR_NAME = "collaboration";
private static final SingleTypeJAXBManager jaxb = SingleTypeJAXBManager
.createWithoutException(ColorInfoMap.class);
+ private ColorInfoMap colorInfoMap;
+
/**
* Set and store the given foreground and background colors for the given
* user/site at the given file location.
@@ -118,11 +126,11 @@ public abstract class AbstractColorConfigManager {
return null;
}
- public abstract void setColors(String key, RGB foreground, RGB background);
+ protected ColorInfoMap getColorInfoMap() {
+ return colorInfoMap;
+ }
- public abstract ColorInfo getColor(String key);
-
- protected abstract ColorInfoMap getColorInfoMap();
-
- protected abstract void setColorInfoMap(ColorInfoMap colorInfo);
+ protected void setColorInfoMap(ColorInfoMap colorInfo) {
+ this.colorInfoMap = colorInfo;
+ }
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/RoomSpecificColorConfigManager.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/RoomSpecificColorConfigManager.java
new file mode 100644
index 0000000000..0ee1ac6926
--- /dev/null
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/RoomSpecificColorConfigManager.java
@@ -0,0 +1,119 @@
+/**
+ * This software was developed and / or modified by Raytheon Company,
+ * pursuant to Contract DG133W-05-CQ-1067 with the US Government.
+ *
+ * U.S. EXPORT CONTROLLED TECHNICAL DATA
+ * This software product contains export-restricted data whose
+ * export/transfer/disclosure is restricted by U.S. law. Dissemination
+ * to non-U.S. persons whether in the United States or abroad requires
+ * an export license or other authorization.
+ *
+ * Contractor Name: Raytheon Company
+ * Contractor Address: 6825 Pine Street, Suite 340
+ * Mail Stop B8
+ * Omaha, NE 68106
+ * 402.291.0100
+ *
+ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
+ * further licensing information.
+ **/
+package com.raytheon.uf.viz.collaboration.ui.colors;
+
+import org.eclipse.swt.graphics.RGB;
+
+import com.raytheon.uf.common.localization.IPathManager;
+import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
+import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueId;
+import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
+
+/**
+ * Keeps track of custom user color configurations for users in a particular
+ * chat room
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 08, 2015 3709 bclement Initial creation
+ *
+ *
+ *
+ * @author bclement
+ * @version 1.0
+ */
+public class RoomSpecificColorConfigManager extends
+ PersistentColorConfigManager {
+
+ private static final String ROOM_CONFIG_DIR = CONFIG_DIR_NAME
+ + IPathManager.SEPARATOR + "roomColors";
+
+ private final String roomId;
+
+ private final String configFilePath;
+
+ /**
+ * @param roomId
+ * @return
+ */
+ public static RoomSpecificColorConfigManager getManagerForRoom(String roomId) {
+ /*
+ * if multiple managers are created for the same room, it could cause
+ * concurrency issues with writing to localization. This could be solved
+ * with a soft reference cache here. However, since there *should* only
+ * be one of these per room id, it might be overkill
+ */
+ return new RoomSpecificColorConfigManager(roomId);
+ }
+
+ /**
+ * @param roomId
+ */
+ protected RoomSpecificColorConfigManager(String roomId) {
+ this.roomId = roomId;
+ this.configFilePath = ROOM_CONFIG_DIR + IPathManager.SEPARATOR + roomId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.raytheon.uf.viz.collaboration.ui.AbstractColorConfigManager#setColors
+ * (java.lang.String, org.eclipse.swt.graphics.RGB,
+ * org.eclipse.swt.graphics.RGB)
+ */
+ @Override
+ public synchronized void setColors(String participant, RGB foreground,
+ RGB background) {
+ super.setColors(participant, foreground, background, configFilePath);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.raytheon.uf.viz.collaboration.ui.AbstractColorConfigManager#getColor
+ * (java.lang.String)
+ */
+ @Override
+ public synchronized ColorInfo getColor(String participant) {
+ return super.getColor(participant, configFilePath);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.raytheon.uf.viz.collaboration.ui.colors.IColorConfigManager#
+ * getDescription()
+ */
+ @Override
+ public String getDescription(String key) {
+ VenueParticipant id = IDConverter.convertFromRoom(null, key);
+ VenueId venue = VenueId.fromString(roomId);
+ return "Color changes will apply to the user " + id.getName()
+ + " only in the " + venue.getName() + " room.";
+ }
+
+}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/TemporaryColorConfigManager.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/TemporaryColorConfigManager.java
new file mode 100644
index 0000000000..00cacafb33
--- /dev/null
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/TemporaryColorConfigManager.java
@@ -0,0 +1,103 @@
+/**
+ * This software was developed and / or modified by Raytheon Company,
+ * pursuant to Contract DG133W-05-CQ-1067 with the US Government.
+ *
+ * U.S. EXPORT CONTROLLED TECHNICAL DATA
+ * This software product contains export-restricted data whose
+ * export/transfer/disclosure is restricted by U.S. law. Dissemination
+ * to non-U.S. persons whether in the United States or abroad requires
+ * an export license or other authorization.
+ *
+ * Contractor Name: Raytheon Company
+ * Contractor Address: 6825 Pine Street, Suite 340
+ * Mail Stop B8
+ * Omaha, NE 68106
+ * 402.291.0100
+ *
+ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
+ * further licensing information.
+ **/
+package com.raytheon.uf.viz.collaboration.ui.colors;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.RGB;
+
+import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
+import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueId;
+import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
+
+/**
+ * Non-persistent color configuration manager
+ *
+ *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date Ticket# Engineer Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 08, 2015 3709 bclement Initial creation
+ *
+ *
+ *
+ * @author bclement
+ * @version 1.0
+ */
+public class TemporaryColorConfigManager implements IColorConfigManager {
+
+ private final Map map = new HashMap();
+
+ private final String roomId;
+
+ /**
+ *
+ */
+ public TemporaryColorConfigManager(String roomId) {
+ this.roomId = roomId;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.raytheon.uf.viz.collaboration.ui.colors.IColorConfigManager#setColors
+ * (java.lang.String, org.eclipse.swt.graphics.RGB,
+ * org.eclipse.swt.graphics.RGB)
+ */
+ @Override
+ public void setColors(String key, RGB foreground, RGB background) {
+ ColorInfo info = new ColorInfo();
+ info.setColors(foreground, background);
+ map.put(key, info);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.raytheon.uf.viz.collaboration.ui.colors.IColorConfigManager#getColor
+ * (java.lang.String)
+ */
+ @Override
+ public ColorInfo getColor(String key) {
+ return map.get(key);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.raytheon.uf.viz.collaboration.ui.colors.IColorConfigManager#
+ * getDescription()
+ */
+ @Override
+ public String getDescription(String key) {
+ VenueParticipant id = IDConverter.convertFromRoom(null, key);
+ VenueId venue = VenueId.fromString(roomId);
+ return "Color changes will apply to the user " + id.getName()
+ + " only in the " + venue.getName() + " room. "
+ + "\nColor changes will be discarded when you leave the room.";
+ }
+
+}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UserColorConfigManager.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/UserColorConfigManager.java
similarity index 60%
rename from cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UserColorConfigManager.java
rename to cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/UserColorConfigManager.java
index ea36998790..7c2689f884 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UserColorConfigManager.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/colors/UserColorConfigManager.java
@@ -17,15 +17,18 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
-package com.raytheon.uf.viz.collaboration.ui;
+package com.raytheon.uf.viz.collaboration.ui.colors;
import org.eclipse.swt.graphics.RGB;
import com.raytheon.uf.common.localization.IPathManager;
-import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
+import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
+import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
/**
- * User coloring configuration manager
+ * Custom user coloring configuration manager for use where the user's true
+ * identity is known (eg one-to-one chat)
*
*
*
@@ -34,20 +37,31 @@ import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 13, 2014 3709 mapeters Initial creation.
- * Nov 26, 2014 3709 mapeters Abstracted out code to {@link AbstractColorConfigManager}.
+ * Nov 26, 2014 3709 mapeters Abstracted out code to {@link PersistentColorConfigManager}.
* Dec 08, 2014 3709 mapeters Set foreground and background colors together.
+ * Jan 09, 2015 3709 bclement made into a true singleton, moved colorInfoMap to super
*
*
*
* @author mapeters
* @version 1.0
*/
-public class UserColorConfigManager extends AbstractColorConfigManager {
+public class UserColorConfigManager extends PersistentColorConfigManager {
- private static final String FILE_PATH = "collaboration"
+ private static final String FILE_PATH = CONFIG_DIR_NAME
+ IPathManager.SEPARATOR + "userColorInfo.xml";
- private static ColorInfoMap colorInfoMap;
+ private static UserColorConfigManager instance;
+
+ public static synchronized UserColorConfigManager getInstance() {
+ if (instance == null) {
+ instance = new UserColorConfigManager();
+ }
+ return instance;
+ }
+
+ protected UserColorConfigManager() {
+ }
/**
* Set and store the given colors for the given user.
@@ -73,13 +87,17 @@ public class UserColorConfigManager extends AbstractColorConfigManager {
return super.getColor(user, FILE_PATH);
}
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.raytheon.uf.viz.collaboration.ui.colors.IColorConfigManager#
+ * getDescription()
+ */
@Override
- protected ColorInfoMap getColorInfoMap() {
- return colorInfoMap;
+ public String getDescription(String key) {
+ UserId id = IDConverter.convertFrom(key);
+ return "Color changes will apply to one-on-one chat sessions with user "
+ + id.getName() + ".";
}
- @Override
- protected void setColorInfoMap(ColorInfoMap colorInfoMap) {
- UserColorConfigManager.colorInfoMap = colorInfoMap;
- }
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionView.java
index 9b00c17feb..0698503e44 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionView.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionView.java
@@ -34,7 +34,6 @@ import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
@@ -73,6 +72,7 @@ import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDr
import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingToolLayer;
import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingUIManager;
import com.raytheon.uf.viz.collaboration.ui.Activator;
+import com.raytheon.uf.viz.collaboration.ui.colors.ForegroundColorDlg;
import com.raytheon.uf.viz.core.ContextManager;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
@@ -82,6 +82,7 @@ import com.raytheon.uf.viz.core.rsc.IResourceDataChanged;
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
import com.raytheon.uf.viz.drawing.DrawingToolLayer;
import com.raytheon.uf.viz.drawing.DrawingToolLayer.DrawMode;
+import com.raytheon.viz.ui.dialogs.ICloseCallback;
import com.raytheon.viz.ui.input.EditableManager;
/**
@@ -107,6 +108,7 @@ import com.raytheon.viz.ui.input.EditableManager;
* May 05, 2014 3076 bclement added clear all action
* Jun 30, 2014 1798 bclement added disableCurrentLayer()
* Dev 02, 2014 3709 mapeters added {@link #initComponents()} override
+ * Jan 09, 2015 3709 bclement now uses ForegroundColorDlg for consistency
*
*
*
@@ -248,6 +250,29 @@ public class CollaborationSessionView extends SessionView implements
super.initComponents(parent);
}
+ /**
+ * Callback used in the change color action. Gets the new color from the
+ * dialog and sends a color change event to the session
+ */
+ private final ICloseCallback colorChangeCallback = new ICloseCallback() {
+ public void dialogClosed(Object returnValue) {
+ if (returnValue != null && returnValue instanceof RGB) {
+ RGB rgb = (RGB) returnValue;
+ IStructuredSelection selection = (IStructuredSelection) usersTable
+ .getSelection();
+ VenueParticipant entry = (VenueParticipant) selection
+ .getFirstElement();
+ ColorChangeEvent event = new ColorChangeEvent(entry, rgb);
+ try {
+ session.sendObjectToVenue(event);
+ } catch (CollaborationException e) {
+ statusHandler.handle(Priority.PROBLEM,
+ "Unable to send color change to venue", e);
+ }
+ }
+ }
+ };
+
@Override
protected void createActions() {
super.createActions();
@@ -256,22 +281,12 @@ public class CollaborationSessionView extends SessionView implements
IconUtil.getImageDescriptor(bundle, "change_color.gif")) {
@Override
public void run() {
- ColorDialog dlg = new ColorDialog(Display.getCurrent()
- .getActiveShell());
- RGB rgb = dlg.open();
- if (rgb != null) {
- IStructuredSelection selection = (IStructuredSelection) usersTable
- .getSelection();
- VenueParticipant entry = (VenueParticipant) selection
- .getFirstElement();
- ColorChangeEvent event = new ColorChangeEvent(entry, rgb);
- try {
- session.sendObjectToVenue(event);
- } catch (CollaborationException e) {
- statusHandler.handle(Priority.PROBLEM,
- "Unable to send color change to venue", e);
- }
- }
+ ForegroundColorDlg dlg = new ForegroundColorDlg(Display
+ .getCurrent().getActiveShell(),
+ "Color changes will be seen by all participants of the "
+ + session.getVenueName() + " session.");
+ dlg.setCloseCallback(colorChangeCallback);
+ dlg.open();
}
};
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/PeerToPeerView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/PeerToPeerView.java
index 72dce4af5e..ef9055d8cc 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/PeerToPeerView.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/PeerToPeerView.java
@@ -49,10 +49,10 @@ import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationC
import com.raytheon.uf.viz.collaboration.comm.provider.user.RosterItem;
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
-import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
-import com.raytheon.uf.viz.collaboration.ui.UserColorConfigManager;
import com.raytheon.uf.viz.collaboration.ui.actions.ChangeTextColorAction;
import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
+import com.raytheon.uf.viz.collaboration.ui.colors.UserColorConfigManager;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTask;
import com.raytheon.uf.viz.collaboration.ui.notifier.NotifierTools;
import com.raytheon.uf.viz.core.sounds.SoundUtil;
@@ -77,6 +77,7 @@ import com.raytheon.uf.viz.core.sounds.SoundUtil;
* Dec 08, 2014 3709 mapeters move color change actions to menu bar.
* Dec 12, 2014 3709 mapeters Store {@link ChangeTextColorAction}s as fields,
* dispose them.
+ * Jan 09, 2015 3709 bclement color config manager API changes
*
*
*
@@ -241,7 +242,7 @@ public class PeerToPeerView extends AbstractSessionView implements
if (userId != null) {
// get user colors from config manager
ColorInfo userColor = colorConfigManager.getColor(userId
- .getName());
+ .getFQName());
if (userColor != null) {
fgColor = getColorFromRGB(userColor.getColor(SWT.FOREGROUND));
bgColor = getColorFromRGB(userColor.getColor(SWT.BACKGROUND));
@@ -329,7 +330,7 @@ public class PeerToPeerView extends AbstractSessionView implements
@Override
protected void initComponents(Composite parent) {
super.initComponents(parent);
- colorConfigManager = new UserColorConfigManager();
+ colorConfigManager = UserColorConfigManager.getInstance();
// unfortunately this code cannot be a part of createToolbarButton
// because I cannot instantiate the ACI until after the messagesText
@@ -398,11 +399,10 @@ public class PeerToPeerView extends AbstractSessionView implements
*/
private void createDropDownMenu() {
IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
- String myName = CollaborationConnection.getConnection().getUser()
- .getName();
+ UserId myUser = CollaborationConnection.getConnection().getUser();
RGB defaultUserForeground = DEFAULT_USER_FOREGROUND_COLOR.getRGB();
userColorAction = ChangeTextColorAction
- .createChangeUserTextColorAction(myName, true, true,
+ .createChangeUserTextColorAction(myUser, true, true,
defaultUserForeground, colorConfigManager);
mgr.add(userColorAction);
}
@@ -412,10 +412,9 @@ public class PeerToPeerView extends AbstractSessionView implements
*/
public void addChangePeerColorAction() {
IMenuManager mgr = getViewSite().getActionBars().getMenuManager();
- String peerName = peer.getName();
RGB defaultPeerForeground = DEFAULT_PEER_FOREGROUND_COLOR.getRGB();
peerColorAction = ChangeTextColorAction
- .createChangeUserTextColorAction(peerName, false, true,
+ .createChangeUserTextColorAction(peer, false, true,
defaultPeerForeground, colorConfigManager);
mgr.add(peerColorAction);
}
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionFeedView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionFeedView.java
index 9a2d79948c..4138ad0a51 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionFeedView.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionFeedView.java
@@ -43,10 +43,10 @@ import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformatio
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
import com.raytheon.uf.viz.collaboration.ui.Activator;
-import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
-import com.raytheon.uf.viz.collaboration.ui.FeedColorConfigManager;
import com.raytheon.uf.viz.collaboration.ui.SiteConfigurationManager;
import com.raytheon.uf.viz.collaboration.ui.actions.ChangeTextColorAction;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
+import com.raytheon.uf.viz.collaboration.ui.colors.FeedColorConfigManager;
import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
/**
@@ -79,6 +79,7 @@ import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
* Dec 08, 2014 3709 mapeters Removed ChangeSiteColorAction, uses {@link ChangeTextColorAction}.
* Dec 12, 2014 3709 mapeters Store {@link ChangeTextColorAction}s in map, dispose them.
* Jan 05, 2015 3709 mapeters Use both site and user name as key in siteColorActions map.
+ * Jan 09, 2015 3709 bclement color config manager API changes
*
*
*
@@ -131,7 +132,7 @@ public class SessionFeedView extends SessionView {
enableUserColors = false;
super.initComponents(parent);
- colorConfigManager = new FeedColorConfigManager();
+ colorConfigManager = FeedColorConfigManager.getInstance();
usersTable.refresh();
siteColorActions = new HashMap<>();
diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionView.java
index 7c980c8ffc..be06fbb027 100644
--- a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionView.java
+++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionView.java
@@ -83,11 +83,13 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
import com.raytheon.uf.viz.collaboration.display.data.SessionColorManager;
import com.raytheon.uf.viz.collaboration.ui.Activator;
-import com.raytheon.uf.viz.collaboration.ui.ColorInfoMap.ColorInfo;
-import com.raytheon.uf.viz.collaboration.ui.UserColorConfigManager;
import com.raytheon.uf.viz.collaboration.ui.actions.ChangeTextColorAction;
import com.raytheon.uf.viz.collaboration.ui.actions.PeerToPeerChatAction;
import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem;
+import com.raytheon.uf.viz.collaboration.ui.colors.ColorInfoMap.ColorInfo;
+import com.raytheon.uf.viz.collaboration.ui.colors.IColorConfigManager;
+import com.raytheon.uf.viz.collaboration.ui.colors.RoomSpecificColorConfigManager;
+import com.raytheon.uf.viz.collaboration.ui.colors.TemporaryColorConfigManager;
import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.sounds.SoundUtil;
@@ -122,6 +124,7 @@ import com.raytheon.uf.viz.core.sounds.SoundUtil;
* use parent's colors map.
* Dec 02, 2014 3709 mapeters added color actions for group chats without shared display.
* Dec 12, 2014 3709 mapeters Store {@link ChangeTextColorAction}s in map, dispose them.
+ * Jan 09, 2015 3709 bclement color config manager API changes
*
*
*
@@ -155,7 +158,7 @@ public class SessionView extends AbstractSessionView
protected SessionColorManager colorManager;
- private static UserColorConfigManager colorConfigManager;
+ private IColorConfigManager colorConfigManager;
private Map userColorActions;
@@ -183,7 +186,14 @@ public class SessionView extends AbstractSessionView
initColorManager();
super.initComponents(parent);
if (enableUserColors) {
- colorConfigManager = new UserColorConfigManager();
+ IVenue venue = session.getVenue();
+ if (venue.isPersistent()) {
+ colorConfigManager = RoomSpecificColorConfigManager
+ .getManagerForRoom(venue.getId());
+ } else {
+ colorConfigManager = new TemporaryColorConfigManager(
+ venue.getId());
+ }
userColorActions = new HashMap<>();
}
@@ -241,14 +251,15 @@ public class SessionView extends AbstractSessionView
}
if (enableUserColors) {
// add color actions if in group chat room without shared display
- String user = entry.getName();
+ String colorActionKey = entry.getFQName();
RGB defaultForeground = colorManager.getColorForUser(entry);
- ChangeTextColorAction userColorAction = userColorActions.get(user);
+ ChangeTextColorAction userColorAction = userColorActions
+ .get(colorActionKey);
if (userColorAction == null) {
userColorAction = ChangeTextColorAction
- .createChangeUserTextColorAction(user, me, me,
+ .createChangeUserTextColorAction(entry, me, me,
defaultForeground, colorConfigManager);
- userColorActions.put(user, userColorAction);
+ userColorActions.put(colorActionKey, userColorAction);
}
manager.add(userColorAction);
}
@@ -522,9 +533,10 @@ public class SessionView extends AbstractSessionView
protected void styleAndAppendText(StringBuilder sb, int offset,
String name, VenueParticipant userId, List ranges,
Color fgColor, Color bgColor, String subject) {
- if (enableUserColors && name != null) {
+ if (enableUserColors && userId != null) {
// Color text by user if in group chat room without shared display
- ColorInfo userColor = colorConfigManager.getColor(name);
+ ColorInfo userColor = colorConfigManager.getColor(userId
+ .getFQName());
if (userColor != null) {
fgColor = getColorFromRGB(userColor.getColor(SWT.FOREGROUND));
bgColor = getColorFromRGB(userColor.getColor(SWT.BACKGROUND));
diff --git a/cave/com.raytheon.uf.viz.monitor.fog/src/com/raytheon/uf/viz/monitor/fog/FogMonitor.java b/cave/com.raytheon.uf.viz.monitor.fog/src/com/raytheon/uf/viz/monitor/fog/FogMonitor.java
old mode 100644
new mode 100755
index 5f91321daf..c56a035e74
--- a/cave/com.raytheon.uf.viz.monitor.fog/src/com/raytheon/uf/viz/monitor/fog/FogMonitor.java
+++ b/cave/com.raytheon.uf.viz.monitor.fog/src/com/raytheon/uf/viz/monitor/fog/FogMonitor.java
@@ -29,9 +29,6 @@ import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Pattern;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
@@ -40,20 +37,17 @@ import com.raytheon.uf.common.dataplugin.fog.FogRecord.FOG_THREAT;
import com.raytheon.uf.common.geospatial.SpatialException;
import com.raytheon.uf.common.monitor.MonitorAreaUtils;
import com.raytheon.uf.common.monitor.config.FSSObsMonitorConfigurationManager;
-import com.raytheon.uf.common.monitor.config.FSSObsMonitorConfigurationManager.MonName;
import com.raytheon.uf.common.monitor.data.AdjacentWfoMgr;
import com.raytheon.uf.common.monitor.data.CommonConfig;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
-import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.alerts.AlertMessage;
import com.raytheon.uf.viz.core.notification.NotificationMessage;
import com.raytheon.uf.viz.monitor.IMonitor;
import com.raytheon.uf.viz.monitor.Monitor;
import com.raytheon.uf.viz.monitor.ObsMonitor;
import com.raytheon.uf.viz.monitor.data.AreaContainer;
-import com.raytheon.uf.viz.monitor.data.MonitoringArea;
import com.raytheon.uf.viz.monitor.data.ObMultiHrsReports;
import com.raytheon.uf.viz.monitor.data.ObReport;
import com.raytheon.uf.viz.monitor.data.ObsData;
@@ -65,7 +59,6 @@ import com.raytheon.uf.viz.monitor.fog.threshold.FogThresholdMgr;
import com.raytheon.uf.viz.monitor.fog.ui.dialogs.FogMonitoringAreaConfigDlg;
import com.raytheon.uf.viz.monitor.fog.ui.dialogs.FogZoneTableDlg;
import com.raytheon.uf.viz.monitor.ui.dialogs.MonitoringAreaConfigDlg;
-import com.raytheon.uf.viz.monitor.util.MonitorThresholdConfiguration;
import com.raytheon.viz.alerts.observers.ProductAlertObserver;
import com.raytheon.viz.ui.dialogs.ICloseCallback;
import com.vividsolutions.jts.geom.Geometry;
@@ -93,6 +86,7 @@ import com.vividsolutions.jts.geom.Geometry;
* Sep 23, 2014 3356 njensen Remove unnecessary import
* Oct 16, 2014 3220 skorolev Corrected fogConfig assignment.
* Dec 11, 2014 3220 skorolev Moved refreshing of table in the UI thread.
+ * Jan 08, 2015 3220 skorolev Replaced MonitoringArea with fogConfig.
*
*
*
@@ -165,12 +159,10 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
private FogMonitor() {
pluginPatterns.add(fogPattern);
fogConfig = FSSObsMonitorConfigurationManager.getFogObsManager();
- updateMonitoringArea();
initObserver(OBS, this);
obData = new ObMultiHrsReports(CommonConfig.AppName.FOG);
obData.setThresholdMgr(FogThresholdMgr.getInstance());
obData.getZoneTableData();
- readTableConfig(MonitorThresholdConfiguration.FOG_THRESHOLD_CONFIG);
}
/**
@@ -184,7 +176,8 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
// Pre-populate dialog with an observations from DB
monitor.createDataStructures();
monitor.getAdjAreas();
- monitor.processProductAtStartup(MonName.fog.name());
+ List zones = monitor.fogConfig.getAreaList();
+ monitor.processProductAtStartup(zones);
monitor.fireMonitorEvent(monitor);
}
@@ -215,8 +208,8 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
obsData = new ObsData();
algorithmData = new TreeMap>();
- for (String zone : MonitoringArea.getPlatformMap().keySet()) {
- obsData.addArea(zone, MonitoringArea.getPlatformMap().get(zone));
+ for (String zone : fogConfig.getAreaList()) {
+ obsData.addArea(zone, fogConfig.getAreaStations(zone));
}
}
@@ -254,38 +247,11 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
@Override
public void processProductMessage(final AlertMessage filtered) {
if (fogPattern.matcher(filtered.dataURI).matches()) {
- processURI(filtered.dataURI, filtered);
+ List zones = fogConfig.getAreaList();
+ processURI(filtered.dataURI, filtered, zones);
}
}
- /**
- * Method that reads the table configuration and updates the zone monitor
- * threshold map
- *
- * @param file
- * -- the xml configuration filename
- */
- public void readTableConfig(String file) {
- // TODO update for Maritime
- Map> zones = new HashMap>();
- // create zones and stations list
- try {
- for (String zone : fogConfig.getAreaList()) {
- // add the unique
- List stations = fogConfig.getAreaStations(zone);
- zones.put(zone, stations);
- }
- } catch (Exception ve) {
- String msg = "FOG Monitor failed to load configuration..."
- + this.getClass().getName();
- ErrorDialog.openError(Display.getCurrent().getActiveShell(),
- "FOG Monitor failed to load configuration", msg,
- new Status(IStatus.ERROR, Activator.PLUGIN_ID, msg, ve));
-
- }
- MonitoringArea.setPlatformMap(zones);
- }
-
/*
* (non-Javadoc)
*
@@ -319,17 +285,9 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
@Override
public void configUpdate(IMonitorConfigurationEvent me) {
fogConfig = (FSSObsMonitorConfigurationManager) me.getSource();
- updateMonitoringArea();
if (zoneDialog != null && !zoneDialog.isDisposed()) {
- VizApp.runAsync(new Runnable() {
-
- @Override
- public void run() {
- zoneDialog.refreshZoneTableData(obData);
- fireMonitorEvent(zoneDialog.getClass().getName());
- }
- });
-
+ zoneDialog.refreshZoneTableData(obData);
+ fireMonitorEvent(zoneDialog.getClass().getName());
}
}
@@ -343,21 +301,6 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
monitor = null;
}
- /**
- * Finds the zone based on the icao passed into it
- *
- * @param icao
- * @return zone
- */
- public String findZone(String icao) {
- for (String zone : MonitoringArea.getPlatformMap().keySet()) {
- if (MonitoringArea.getPlatformMap().get(zone).contains(icao)) {
- return zone;
- }
- }
- return null;
- }
-
/**
* Gets the main map
*
@@ -377,12 +320,16 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
@Override
protected void process(ObReport result) throws Exception {
obData.addReport(result);
- String zone = findZone(result.getPlatformId());
- if (zone != null) {
- AreaContainer ac = getTableData().getArea(zone);
- if (ac != null) {
- ac.addReport(result.getObservationTime(), result);
- fireMonitorEvent(this);
+ // Get zones containing station
+ List zones = fogConfig.getAreaByStationId(result
+ .getPlatformId());
+ if (!zones.isEmpty() || zones != null) {
+ for (String zn : zones) {
+ AreaContainer ac = getTableData().getArea(zn);
+ if (ac != null) {
+ ac.addReport(result.getObservationTime(), result);
+ fireMonitorEvent(this);
+ }
}
}
}
@@ -455,7 +402,7 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
algData = algorithmData.get(time);
} else {
// by default is nothing in the ALG column
- for (String zone : MonitoringArea.getPlatformMap().keySet()) {
+ for (String zone : fogConfig.getAreaList()) {
algData.put(zone, FOG_THREAT.GRAY);
}
}
@@ -632,9 +579,14 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
@Override
protected void processAtStartup(ObReport report) {
obData.addReport(report);
- String zone = findZone(report.getPlatformId());
- getTableData().getArea(zone).addReport(report.getObservationTime(),
- report);
+ List zones = fogConfig.getAreaByStationId(report
+ .getPlatformId());
+ if (!zones.isEmpty() || zones != null) {
+ for (String zn : zones) {
+ getTableData().getArea(zn).addReport(
+ report.getObservationTime(), report);
+ }
+ }
}
/**
@@ -647,19 +599,11 @@ public class FogMonitor extends ObsMonitor implements IFogResourceListener {
}
/**
- * Reads Table Configuration.
- *
- * Method that reads the table configuration and updates the zone monitor
- * threshold map
+ * Gets Fog Area configuration dialog
*
+ * @return
*/
- private void updateMonitoringArea() {
- Map> zones = new HashMap>();
- // create zones and station list
- for (String zone : fogConfig.getAreaList()) {
- List stations = fogConfig.getAreaStations(zone);
- zones.put(zone, stations);
- }
- MonitoringArea.setPlatformMap(zones);
+ public MonitoringAreaConfigDlg getAreaDialog() {
+ return areaDialog;
}
}
diff --git a/cave/com.raytheon.uf.viz.monitor.fog/src/com/raytheon/uf/viz/monitor/fog/ui/actions/FogAreaConfigAction.java b/cave/com.raytheon.uf.viz.monitor.fog/src/com/raytheon/uf/viz/monitor/fog/ui/actions/FogAreaConfigAction.java
index b8d0d6cfd3..468814df30 100644
--- a/cave/com.raytheon.uf.viz.monitor.fog/src/com/raytheon/uf/viz/monitor/fog/ui/actions/FogAreaConfigAction.java
+++ b/cave/com.raytheon.uf.viz.monitor.fog/src/com/raytheon/uf/viz/monitor/fog/ui/actions/FogAreaConfigAction.java
@@ -25,8 +25,8 @@ import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
+import com.raytheon.uf.viz.monitor.fog.FogMonitor;
import com.raytheon.uf.viz.monitor.fog.ui.dialogs.FogMonitoringAreaConfigDlg;
-import com.raytheon.viz.ui.dialogs.ICloseCallback;
/**
* The Fog Monitor Action
@@ -42,6 +42,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* May 08, 2014 3086 skorolev Added CloseCallback to dialog.
* Sep 16, 2014 2757 skorolev Added test of dialog on dispose.
* Sep 19, 2014 3220 skorolev Added check on dispose.
+ * Jan 08, 2015 3220 skorolev Used area type for launchDialog.
*
*
*
@@ -65,19 +66,13 @@ public class FogAreaConfigAction extends AbstractHandler {
*/
@Override
public Object execute(ExecutionEvent arg0) throws ExecutionException {
- if (areaDialog == null || areaDialog.isDisposed()) {
+ FogMonitor fog = FogMonitor.getInstance();
+
+ if (fog.getAreaDialog() == null || fog.getAreaDialog().isDisposed()) {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
- areaDialog = new FogMonitoringAreaConfigDlg(shell,
- "Fog Monitor Area Configuration");
- areaDialog.setCloseCallback(new ICloseCallback() {
- @Override
- public void dialogClosed(Object returnValue) {
- areaDialog = null;
- }
- });
+ fog.launchDialog("area", shell);
}
- areaDialog.open();
return null;
}
}
diff --git a/cave/com.raytheon.uf.viz.monitor.safeseas/src/com/raytheon/uf/viz/monitor/safeseas/SafeSeasMonitor.java b/cave/com.raytheon.uf.viz.monitor.safeseas/src/com/raytheon/uf/viz/monitor/safeseas/SafeSeasMonitor.java
old mode 100644
new mode 100755
index f5b980ac35..e5eb2ad0b5
--- a/cave/com.raytheon.uf.viz.monitor.safeseas/src/com/raytheon/uf/viz/monitor/safeseas/SafeSeasMonitor.java
+++ b/cave/com.raytheon.uf.viz.monitor.safeseas/src/com/raytheon/uf/viz/monitor/safeseas/SafeSeasMonitor.java
@@ -42,14 +42,12 @@ import com.raytheon.uf.common.monitor.data.CommonConfig;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
-import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.alerts.AlertMessage;
import com.raytheon.uf.viz.core.notification.NotificationMessage;
import com.raytheon.uf.viz.monitor.IMonitor;
import com.raytheon.uf.viz.monitor.Monitor;
import com.raytheon.uf.viz.monitor.ObsMonitor;
import com.raytheon.uf.viz.monitor.config.CommonTableConfig.CellType;
-import com.raytheon.uf.viz.monitor.data.MonitoringArea;
import com.raytheon.uf.viz.monitor.data.ObMultiHrsReports;
import com.raytheon.uf.viz.monitor.data.ObReport;
import com.raytheon.uf.viz.monitor.data.TableCellData;
@@ -61,8 +59,6 @@ import com.raytheon.uf.viz.monitor.safeseas.listeners.ISSResourceListener;
import com.raytheon.uf.viz.monitor.safeseas.threshold.SSThresholdMgr;
import com.raytheon.uf.viz.monitor.safeseas.ui.dialogs.SSMonitoringAreaConfigDlg;
import com.raytheon.uf.viz.monitor.safeseas.ui.dialogs.SSZoneTableDlg;
-import com.raytheon.uf.viz.monitor.ui.dialogs.ZoneTableDlg;
-import com.raytheon.uf.viz.monitor.util.MonitorThresholdConfiguration;
import com.raytheon.viz.alerts.observers.ProductAlertObserver;
import com.raytheon.viz.ui.dialogs.ICloseCallback;
import com.vividsolutions.jts.geom.Geometry;
@@ -89,6 +85,7 @@ import com.vividsolutions.jts.geom.Geometry;
* Sep 04, 2014 3220 skorolev Updated configUpdate method and added updateMonitoringArea.
* Oct 16, 2014 3220 skorolev Corrected ssAreaConfig assignment.
* Dec 11, 2014 3220 skorolev Moved refreshing of table in the UI thread.
+ * Jan 08, 2015 3220 skorolev Replaced MonitoringArea with ssAreaConfig.
*
*
*
@@ -164,13 +161,10 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
private SafeSeasMonitor() {
pluginPatterns.add(ssPattern);
ssAreaConfig = FSSObsMonitorConfigurationManager.getSsObsManager();
- updateMonitoringArea();
initObserver(OBS, this);
obData = new ObMultiHrsReports(CommonConfig.AppName.SAFESEAS);
obData.setThresholdMgr(SSThresholdMgr.getInstance());
obData.getZoneTableData();
- readTableConfig(MonitorThresholdConfiguration.SAFESEAS_THRESHOLD_CONFIG);
-
}
/**
@@ -182,7 +176,8 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
// Pre-populate dialog with an observation (METAR) for KOMA
monitor.createDataStructures();
monitor.getAdjAreas();
- monitor.processProductAtStartup("ss");
+ List zones = monitor.ssAreaConfig.getAreaList();
+ monitor.processProductAtStartup(zones);
monitor.fireMonitorEvent(monitor);
}
return monitor;
@@ -228,7 +223,7 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
} else if (type.equals("area")) {
if (areaDialog == null) {
areaDialog = new SSMonitoringAreaConfigDlg(shell,
- "Safe Seas Monitor Area Configuration");
+ "SAFESEAS Monitor Area Configuration");
areaDialog.setCloseCallback(new ICloseCallback() {
@Override
@@ -276,7 +271,8 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
@Override
public void processProductMessage(final AlertMessage filtered) {
if (ssPattern.matcher(filtered.dataURI).matches()) {
- processURI(filtered.dataURI, filtered);
+ final List zones = ssAreaConfig.getAreaList();
+ processURI(filtered.dataURI, filtered, zones);
}
}
@@ -299,31 +295,6 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
stationTableData.addReplaceDataRow(stationRowData);
}
- /**
- * Reads Table Configuration.
- *
- * Method that reads the table configuration and updates the zone monitor
- * threshold map
- *
- * @param file
- * -- the xml configuration filename
- */
- public void readTableConfig(String file) {
- Map> zones = new HashMap>();
- // create zones and station list
- try {
- for (String zone : ssAreaConfig.getAreaList()) {
- List stations = ssAreaConfig.getAreaStations(zone);
- zones.put(zone, stations);
- }
- } catch (Exception e) {
- statusHandler.handle(Priority.CRITICAL,
- "SafeSeas failed to load configuration..."
- + this.getClass().getName(), e);
- }
- MonitoringArea.setPlatformMap(zones);
- }
-
/*
* (non-Javadoc)
*
@@ -357,18 +328,8 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
@Override
public void configUpdate(IMonitorConfigurationEvent me) {
ssAreaConfig = (FSSObsMonitorConfigurationManager) me.getSource();
- updateMonitoringArea();
- if (zoneDialog != null && !zoneDialog.isDisposed()) {
- VizApp.runAsync(new Runnable() {
-
- @Override
- public void run() {
- zoneDialog.refreshZoneTableData(obData);
- fireMonitorEvent(zoneDialog.getClass().getName());
- }
-
- });
- }
+ zoneDialog.refreshZoneTableData(obData);
+ fireMonitorEvent(zoneDialog.getClass().getName());
}
/**
@@ -553,7 +514,7 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
algData = algorithmData.get(time);
} else {
// by default is nothing in the Fog column
- for (String zone : MonitoringArea.getPlatformMap().keySet()) {
+ for (String zone : ssAreaConfig.getAreaList()) {
algData.put(zone, FOG_THREAT.GRAY);
}
}
@@ -594,15 +555,6 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
return type;
}
- /**
- * Gets zone dialog
- *
- * @return zoneDialog
- */
- public ZoneTableDlg getDialog() {
- return zoneDialog;
- }
-
/**
* Gets adjacent areas
*/
@@ -679,19 +631,11 @@ public class SafeSeasMonitor extends ObsMonitor implements ISSResourceListener {
}
/**
- * Reads Table Configuration.
- *
- * Method that reads the table configuration and updates the zone monitor
- * threshold map
+ * Gets SAFESEAS Area configuration dialog
*
+ * @return
*/
- public void updateMonitoringArea() {
- Map> zones = new HashMap>();
- // create zones and station list
- for (String zone : ssAreaConfig.getAreaList()) {
- List stations = ssAreaConfig.getAreaStations(zone);
- zones.put(zone, stations);
- }
- MonitoringArea.setPlatformMap(zones);
+ public SSMonitoringAreaConfigDlg getAreaDialog() {
+ return areaDialog;
}
}
diff --git a/cave/com.raytheon.uf.viz.monitor.safeseas/src/com/raytheon/uf/viz/monitor/safeseas/ui/actions/SafeseasAreaConfigAction.java b/cave/com.raytheon.uf.viz.monitor.safeseas/src/com/raytheon/uf/viz/monitor/safeseas/ui/actions/SafeseasAreaConfigAction.java
index 72cc4046fb..987d3cb2c6 100644
--- a/cave/com.raytheon.uf.viz.monitor.safeseas/src/com/raytheon/uf/viz/monitor/safeseas/ui/actions/SafeseasAreaConfigAction.java
+++ b/cave/com.raytheon.uf.viz.monitor.safeseas/src/com/raytheon/uf/viz/monitor/safeseas/ui/actions/SafeseasAreaConfigAction.java
@@ -25,8 +25,7 @@ import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
-import com.raytheon.uf.viz.monitor.safeseas.ui.dialogs.SSMonitoringAreaConfigDlg;
-import com.raytheon.viz.ui.dialogs.ICloseCallback;
+import com.raytheon.uf.viz.monitor.safeseas.SafeSeasMonitor;
/**
* The SAFESEAS Action
@@ -42,6 +41,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* May 08, 2014 3086 skorolev Added CloseCallback to dialog.
* Sep 16, 2014 2757 skorolev Added test of dialog on dispose.
* Sep 19, 2014 3220 skorolev Added check on dispose.
+ * Jan 08, 2015 3220 skorolev Used area type for launchDialog.
*
*
*
@@ -51,11 +51,6 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
public class SafeseasAreaConfigAction extends AbstractHandler {
- /**
- * SAFESEAS Monitoring Area Configuration Dialog.
- */
- private SSMonitoringAreaConfigDlg configDlg;
-
/*
* (non-Javadoc)
*
@@ -65,19 +60,14 @@ public class SafeseasAreaConfigAction extends AbstractHandler {
*/
@Override
public Object execute(ExecutionEvent arg0) throws ExecutionException {
- if (configDlg == null || configDlg.isDisposed()) {
+
+ SafeSeasMonitor monitor = SafeSeasMonitor.getInstance();
+ if (monitor.getAreaDialog() == null
+ || monitor.getAreaDialog().isDisposed()) {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
- configDlg = new SSMonitoringAreaConfigDlg(shell,
- "SAFESEAS Monitor Area Configuration");
- configDlg.setCloseCallback(new ICloseCallback() {
- @Override
- public void dialogClosed(Object returnValue) {
- configDlg = null;
- }
- });
+ monitor.launchDialog("area", shell);
}
- configDlg.open();
return null;
}
}
diff --git a/cave/com.raytheon.uf.viz.monitor.snow/src/com/raytheon/uf/viz/monitor/snow/SnowMonitor.java b/cave/com.raytheon.uf.viz.monitor.snow/src/com/raytheon/uf/viz/monitor/snow/SnowMonitor.java
old mode 100644
new mode 100755
index c4cf314362..db83ef1be3
--- a/cave/com.raytheon.uf.viz.monitor.snow/src/com/raytheon/uf/viz/monitor/snow/SnowMonitor.java
+++ b/cave/com.raytheon.uf.viz.monitor.snow/src/com/raytheon/uf/viz/monitor/snow/SnowMonitor.java
@@ -22,9 +22,7 @@ package com.raytheon.uf.viz.monitor.snow;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.regex.Pattern;
import org.eclipse.swt.widgets.Shell;
@@ -34,13 +32,11 @@ import com.raytheon.uf.common.monitor.config.FSSObsMonitorConfigurationManager;
import com.raytheon.uf.common.monitor.data.CommonConfig;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
-import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.alerts.AlertMessage;
import com.raytheon.uf.viz.core.notification.NotificationMessage;
import com.raytheon.uf.viz.monitor.IMonitor;
import com.raytheon.uf.viz.monitor.Monitor;
import com.raytheon.uf.viz.monitor.ObsMonitor;
-import com.raytheon.uf.viz.monitor.data.MonitoringArea;
import com.raytheon.uf.viz.monitor.data.ObMultiHrsReports;
import com.raytheon.uf.viz.monitor.data.ObReport;
import com.raytheon.uf.viz.monitor.events.IMonitorConfigurationEvent;
@@ -76,6 +72,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
* Sep 04, 2014 3220 skorolev Updated configUpdate method and added updateMonitoringArea.
* Oct 16, 2014 3220 skorolev Corrected snowConfig assignment.
* Dec 11, 2014 3220 skorolev Moved refreshing of table in the UI thread.
+ * Jan 08, 2015 3220 skorolev Replaced MonitoringArea with snowAreaConfig.
*
*
*
@@ -99,7 +96,7 @@ public class SnowMonitor extends ObsMonitor implements ISnowResourceListener {
private SnowMonitoringAreaConfigDlg areaDialog = null;
/** SNOW configuration manager **/
- private FSSObsMonitorConfigurationManager snowConfig = null;
+ private FSSObsMonitorConfigurationManager snowAreaConfig = null;
/**
* This object contains all observation data necessary for the table dialogs
@@ -130,8 +127,7 @@ public class SnowMonitor extends ObsMonitor implements ISnowResourceListener {
*/
private SnowMonitor() {
pluginPatterns.add(snowPattern);
- snowConfig = FSSObsMonitorConfigurationManager.getSnowObsManager();
- updateMonitoringArea();
+ snowAreaConfig = FSSObsMonitorConfigurationManager.getSnowObsManager();
initObserver(OBS, this);
obData = new ObMultiHrsReports(CommonConfig.AppName.SNOW);
obData.setThresholdMgr(SnowThresholdMgr.getInstance());
@@ -146,7 +142,8 @@ public class SnowMonitor extends ObsMonitor implements ISnowResourceListener {
public static synchronized SnowMonitor getInstance() {
if (monitor == null) {
monitor = new SnowMonitor();
- monitor.processProductAtStartup("snow");
+ List zones = monitor.snowAreaConfig.getAreaList();
+ monitor.processProductAtStartup(zones);
monitor.fireMonitorEvent(monitor);
}
return monitor;
@@ -239,7 +236,8 @@ public class SnowMonitor extends ObsMonitor implements ISnowResourceListener {
@Override
public void processProductMessage(final AlertMessage filtered) {
if (snowPattern.matcher(filtered.dataURI).matches()) {
- processURI(filtered.dataURI, filtered);
+ List zones = snowAreaConfig.getAreaList();
+ processURI(filtered.dataURI, filtered, zones);
}
}
@@ -256,23 +254,6 @@ public class SnowMonitor extends ObsMonitor implements ISnowResourceListener {
}
}
- /**
- * Reads Table Configuration.
- *
- * Method that reads the table configuration and updates the zone monitor
- * threshold map
- *
- */
- public void updateMonitoringArea() {
- Map> zones = new HashMap>();
- // create zones and station list
- for (String zone : snowConfig.getAreaList()) {
- List stations = snowConfig.getAreaStations(zone);
- zones.put(zone, stations);
- }
- MonitoringArea.setPlatformMap(zones);
- }
-
/*
* (non-Javadoc)
*
@@ -305,18 +286,10 @@ public class SnowMonitor extends ObsMonitor implements ISnowResourceListener {
*/
@Override
public void configUpdate(IMonitorConfigurationEvent me) {
- snowConfig = (FSSObsMonitorConfigurationManager) me.getSource();
- updateMonitoringArea();
+ snowAreaConfig = (FSSObsMonitorConfigurationManager) me.getSource();
if (zoneDialog != null && !zoneDialog.isDisposed()) {
- VizApp.runAsync(new Runnable() {
-
- @Override
- public void run() {
- zoneDialog.refreshZoneTableData(obData);
- fireMonitorEvent(zoneDialog.getClass().getName());
- }
- });
-
+ zoneDialog.refreshZoneTableData(obData);
+ fireMonitorEvent(zoneDialog.getClass().getName());
}
}
@@ -427,7 +400,7 @@ public class SnowMonitor extends ObsMonitor implements ISnowResourceListener {
}
/**
- * Gets Zone Dialog.
+ * Gets SNOW Zone Dialog.
*
* @return zoneDialog
*/
@@ -435,6 +408,15 @@ public class SnowMonitor extends ObsMonitor implements ISnowResourceListener {
return zoneDialog;
}
+ /**
+ * Gets SNOW Area configuration dialog
+ *
+ * @return
+ */
+ public SnowMonitoringAreaConfigDlg getAreaDialog() {
+ return areaDialog;
+ }
+
/**
* Sets the zoneDialog
*
diff --git a/cave/com.raytheon.uf.viz.monitor.snow/src/com/raytheon/uf/viz/monitor/snow/ui/actions/SnowAreaConfigAction.java b/cave/com.raytheon.uf.viz.monitor.snow/src/com/raytheon/uf/viz/monitor/snow/ui/actions/SnowAreaConfigAction.java
index b4fa508d61..a0f050c516 100644
--- a/cave/com.raytheon.uf.viz.monitor.snow/src/com/raytheon/uf/viz/monitor/snow/ui/actions/SnowAreaConfigAction.java
+++ b/cave/com.raytheon.uf.viz.monitor.snow/src/com/raytheon/uf/viz/monitor/snow/ui/actions/SnowAreaConfigAction.java
@@ -25,8 +25,7 @@ import org.eclipse.core.commands.ExecutionException;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
-import com.raytheon.uf.viz.monitor.snow.ui.dialogs.SnowMonitoringAreaConfigDlg;
-import com.raytheon.viz.ui.dialogs.ICloseCallback;
+import com.raytheon.uf.viz.monitor.snow.SnowMonitor;
/**
* The Snow Area Action
@@ -51,11 +50,6 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
public class SnowAreaConfigAction extends AbstractHandler {
- /**
- * SNOW Monitoring Area Configuration Dialog.
- */
- private SnowMonitoringAreaConfigDlg configDlg;
-
/*
* (non-Javadoc)
*
@@ -65,19 +59,12 @@ public class SnowAreaConfigAction extends AbstractHandler {
*/
@Override
public Object execute(ExecutionEvent arg0) throws ExecutionException {
- if (configDlg == null || configDlg.isDisposed()) {
+ SnowMonitor snow = SnowMonitor.getInstance();
+ if (snow.getAreaDialog() == null || snow.getAreaDialog().isDisposed()) {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell();
- configDlg = new SnowMonitoringAreaConfigDlg(shell,
- "SNOW Monitor Area Configuration");
- configDlg.setCloseCallback(new ICloseCallback() {
- @Override
- public void dialogClosed(Object returnValue) {
- configDlg = null;
- }
- });
+ snow.launchDialog("area", shell);
}
- configDlg.open();
return null;
}
}
\ No newline at end of file
diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ObsMonitor.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ObsMonitor.java
index a1045c3bac..9b8fb92cca 100755
--- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ObsMonitor.java
+++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ObsMonitor.java
@@ -22,11 +22,10 @@ package com.raytheon.uf.viz.monitor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
-import org.eclipse.swt.widgets.Display;
-
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.annotations.DataURIUtil;
import com.raytheon.uf.common.dataplugin.fssobs.FSSObsRecord;
@@ -43,7 +42,6 @@ import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.localization.LocalizationManager;
import com.raytheon.uf.viz.core.notification.NotificationMessage;
import com.raytheon.uf.viz.datacube.DataCubeContainer;
-import com.raytheon.uf.viz.monitor.data.MonitoringArea;
import com.raytheon.uf.viz.monitor.data.ObReport;
import com.raytheon.uf.viz.monitor.events.IMonitorConfigurationEvent;
import com.raytheon.uf.viz.monitor.events.IMonitorThresholdEvent;
@@ -62,6 +60,7 @@ import com.raytheon.uf.viz.monitor.events.IMonitorThresholdEvent;
* Feb 04, 2014 2757 skorolev Added filter for removed stations
* May 08, 2014 3086 skorolev Added current site definition.
* Sep 04, 2014 3220 skorolev Removed cwa and monitorUsefrom vals.
+ * Jan 08, 2015 3220 skorolev Added zones parameter to processURI.
*
*
*
@@ -187,45 +186,29 @@ public abstract class ObsMonitor extends Monitor {
*
* @param dataURI
* @param filtered
+ * @param zones
*/
- public void processURI(String dataURI, AlertMessage filtered) {
+ public void processURI(String dataURI, AlertMessage filtered,
+ final List zones) {
try {
Map constraints = RequestConstraint
.toConstraintMapping(DataURIUtil.createDataURIMap(dataURI));
FSSObsRecord[] pdos = requestFSSObs(constraints, null);
if (pdos.length > 0 && pdos[0].getTimeObs() != null) {
final FSSObsRecord objectToSend = pdos[0];
- try {
- Display.getDefault().asyncExec(new Runnable() {
- public void run() {
- try {
- // Filter removed stations
- ArrayList zones = MonitoringArea
- .getZoneIds(objectToSend
- .getPlatformId());
- if (!zones.isEmpty()) {
- ObReport result = GenerateFSSObReport
- .generateObReport(objectToSend);
- statusHandler
- .handle(Priority.INFO,
- "New FSSrecord ===> "
- + objectToSend
- .getDataURI());
- process(result);
- }
- } catch (Exception e) {
- statusHandler
- .handle(Priority.PROBLEM,
- "An error has occured processing the incoming messages.",
- e);
- }
- }
- });
- } catch (Exception e) {
- statusHandler
- .handle(Priority.PROBLEM,
- "An error has occured processing incoming dataURIs.",
- e);
+ if (!zones.isEmpty()) {
+ ObReport result = GenerateFSSObReport
+ .generateObReport(objectToSend);
+ statusHandler.handle(Priority.INFO, "New FSSrecord ===> "
+ + objectToSend.getDataURI());
+ try {
+ process(result);
+ } catch (Exception e) {
+ statusHandler
+ .handle(Priority.PROBLEM,
+ "An error has occured processing the incoming messages.",
+ e);
+ }
}
}
} catch (final Exception e) {
@@ -237,10 +220,10 @@ public abstract class ObsMonitor extends Monitor {
/**
* Process products at startup
*
- * @param monitorName
+ * @param zones
*
*/
- public void processProductAtStartup(String monitorName) {
+ public void processProductAtStartup(List zones) {
/**
* Assume this number for MaxNumObsTimes is larger enough to cover data
@@ -275,8 +258,6 @@ public abstract class ObsMonitor extends Monitor {
FSSObsRecord[] obsRecords = requestFSSObs(vals, selectedTimes);
for (FSSObsRecord objectToSend : obsRecords) {
// Filter removed stations
- ArrayList zones = MonitoringArea
- .getZoneIds(objectToSend.getPlatformId());
if (!zones.isEmpty()) {
ObReport result = GenerateFSSObReport
.generateObReport(objectToSend);
@@ -286,7 +267,7 @@ public abstract class ObsMonitor extends Monitor {
}
} catch (DataCubeException e) {
statusHandler.handle(Priority.PROBLEM,
- "No data in database at startup. " + monitorName);
+ "No data in database at startup.");
}
}
diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/MonitorAreaThresholds.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/MonitorAreaThresholds.java
old mode 100644
new mode 100755
index b7a517d59e..580ee6470c
--- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/MonitorAreaThresholds.java
+++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/MonitorAreaThresholds.java
@@ -20,8 +20,10 @@
package com.raytheon.uf.viz.monitor.data;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import com.raytheon.uf.common.monitor.config.FSSObsMonitorConfigurationManager;
import com.raytheon.uf.common.monitor.data.ObConst;
import com.raytheon.uf.common.monitor.data.ObConst.ChosenAppKey;
import com.raytheon.uf.common.monitor.data.ObConst.ThreatLevel;
@@ -40,6 +42,7 @@ import com.raytheon.uf.common.monitor.data.ObConst.VarName;
* Feb 17, 2009 1999 grichard Initial creation.
* 3/16/2009 2047 grichard Add threat monitoring routines.
* Dec 24, 2009 3424 zhao added getDualValuedThresholdMap and getSingleValuedThresholdMap
+ * Jan 12, 2015 3220 skorolev Replaced MonitoringArea with areaConfig.
*
*
*
@@ -62,56 +65,6 @@ public final class MonitorAreaThresholds {
// Map containing the display thresholds
private static Map zoneDisplayThresholds = new HashMap();
- /**
- * This method receives an observation report and a variable name, and
- * returns the threat level of that single variable.
- *
- * @param report
- * -- the observation report
- * @param varName
- * -- the variable name within the report
- * @return -- the threat level
- */
- public static ObConst.ThreatLevel getThreatLevel(ObReport report,
- VarName varName) {
-
- ThreatLevel threatLevel = ThreatLevel.GRAY;
- ThreatLevel temp = ThreatLevel.GRAY;
- float varValue = ObConst.MISSING;
-
- try {
- varValue = getReportVarValue(report, varName);
-
- String zoneId = report.getZoneId();
- // TEMPORARILY USE DEFAULT ZONE ID, NAMELY, DEFAULT STATION.
- zoneId = ObConst.DEFAULT_STATION_NAME;
- if (report.isStationary()) {
- if (MonitoringArea.listZonesToPlatform(report.getPlatformId())
- .isEmpty()) {
- // use the default zone if there are no zones
- temp = getZoneThreatLevel(zoneId, varName, varValue);
- if (temp.ordinal() < threatLevel.ordinal()) {
- threatLevel = temp;
- }
- } else {
- for (String z : MonitoringArea.listZonesToPlatform(report
- .getPlatformId())) {
- temp = getZoneThreatLevel(z, varName, varValue);
- if (temp.ordinal() < threatLevel.ordinal()) {
- threatLevel = temp;
- }
- }
- }
- } else {
- temp = getZoneThreatLevel(zoneId, varName, varValue);
- }
- } catch (Exception e) {
- // return the default threat level
- }
-
- return threatLevel;
- }
-
/**
* This method receives an observation report and a variable name, and
* returns the threat level of that single variable.
@@ -127,12 +80,13 @@ public final class MonitorAreaThresholds {
ThreatLevel threatLevel = ThreatLevel.GRAY;
ThreatLevel temp = ThreatLevel.GRAY;
-
+ String station = report.getPlatformId();
try {
if (report.isStationary()) {
if (chosenAppKey == ChosenAppKey.SAFESEAS) {
- if (MonitoringArea.listZonesToPlatform(
- report.getPlatformId()).isEmpty()) {
+ List ssZones = FSSObsMonitorConfigurationManager
+ .getSsObsManager().getAreaByStationId(station);
+ if (ssZones.isEmpty()) {
// use the default zone if there are no zones
for (VarName v : VarName.values()) {
if (v == VarName.TEMPERATURE
@@ -150,8 +104,7 @@ public final class MonitorAreaThresholds {
}
}
} else {
- for (String z : MonitoringArea
- .listZonesToPlatform(report.getPlatformId())) {
+ for (String z : ssZones) {
for (VarName v : VarName.values()) {
if (v == VarName.TEMPERATURE
|| v == VarName.WIND_CHILL
@@ -169,8 +122,9 @@ public final class MonitorAreaThresholds {
}
}
} else if (chosenAppKey == ChosenAppKey.SNOW) {
- if (MonitoringArea.listZonesToPlatform(
- report.getPlatformId()).isEmpty()) {
+ List snowZones = FSSObsMonitorConfigurationManager
+ .getSnowObsManager().getAreaByStationId(station);
+ if (snowZones.isEmpty()) {
// use the default zone if there are no zones
for (VarName v : VarName.values()) {
if (v == VarName.PRIM_SWELL_HT) {
@@ -185,8 +139,7 @@ public final class MonitorAreaThresholds {
}
} else {
- for (String z : MonitoringArea
- .listZonesToPlatform(report.getPlatformId())) {
+ for (String z : snowZones) {
for (VarName v : VarName.values()) {
if (v == VarName.PRIM_SWELL_HT) {
break;
@@ -199,9 +152,10 @@ public final class MonitorAreaThresholds {
}
}
}
- } else {
- if (MonitoringArea.listZonesToPlatform(
- report.getPlatformId()).isEmpty()) {
+ } else {// chosenAppKey = FOG
+ List fogZones = FSSObsMonitorConfigurationManager
+ .getFogObsManager().getAreaByStationId(station);
+ if (fogZones.isEmpty()) {
// use the default zone if there are no zones
temp = getZoneThreatLevel(ObConst.DEFAULT_STATION_NAME,
VarName.PRES_WX, report.getPresentWx());
@@ -209,20 +163,21 @@ public final class MonitorAreaThresholds {
threatLevel = temp;
}
temp = getZoneThreatLevel(ObConst.DEFAULT_STATION_NAME,
- VarName.VISIBILITY, getReportVarValue(report,
- VarName.VISIBILITY));
+ VarName.VISIBILITY,
+ getReportVarValue(report, VarName.VISIBILITY));
if (temp.ordinal() < threatLevel.ordinal()) {
threatLevel = temp;
}
} else {
- for (String z : MonitoringArea
- .listZonesToPlatform(report.getPlatformId())) {
+ for (String z : fogZones) {
temp = getZoneThreatLevel(z, VarName.PRES_WX,
report.getPresentWx());
if (temp.ordinal() < threatLevel.ordinal()) {
threatLevel = temp;
}
- temp = getZoneThreatLevel(z, VarName.VISIBILITY,
+ temp = getZoneThreatLevel(
+ z,
+ VarName.VISIBILITY,
getReportVarValue(report,
VarName.VISIBILITY));
if (temp.ordinal() < threatLevel.ordinal()) {
@@ -231,6 +186,7 @@ public final class MonitorAreaThresholds {
}
}
}
+ // report is not Stationary
} else {
if (chosenAppKey == ChosenAppKey.SAFESEAS) {
String zoneId = report.getZoneId();
@@ -243,8 +199,8 @@ public final class MonitorAreaThresholds {
} else if (v == VarName.STATIONARY) {
break;
}
- temp = getZoneThreatLevel(zoneId, v, getReportVarValue(
- report, v));
+ temp = getZoneThreatLevel(zoneId, v,
+ getReportVarValue(report, v));
if (temp.ordinal() < threatLevel.ordinal()) {
threatLevel = temp;
}
@@ -257,13 +213,13 @@ public final class MonitorAreaThresholds {
if (v == VarName.PRIM_SWELL_HT) {
break;
}
- temp = getZoneThreatLevel(zoneId, v, getReportVarValue(
- report, v));
+ temp = getZoneThreatLevel(zoneId, v,
+ getReportVarValue(report, v));
if (temp.ordinal() < threatLevel.ordinal()) {
threatLevel = temp;
}
}
- } else {
+ } else {// chosenAppKey = FOG
String zoneId = report.getZoneId();
// TEMPORARILY USE DEFAULT ZONE ID, NAMELY, DEFAULT STATION.
zoneId = ObConst.DEFAULT_STATION_NAME;
@@ -605,32 +561,44 @@ public final class MonitorAreaThresholds {
}
return result;
}
-
+
/**
* [Dec 24, 2009, zhao]
- * @param zone the zone ID
- * @param varName enumerated-type variable name
- * @return single-valued threshold map, or null if the variable
- * name is invalid or if the map contains no mapping for the key
+ *
+ * @param zone
+ * the zone ID
+ * @param varName
+ * enumerated-type variable name
+ * @return single-valued threshold map, or null if the variable name is
+ * invalid or if the map contains no mapping for the key
*/
- public static Map getSingleValuedThresholdMap(String zone, ObConst.VarName varName) {
- if (varName == VarName.WIND_DIR || varName == VarName.PRIM_SWELL_DIR || varName == VarName.SEC_SWELL_DIR ) {
- return null;
- }
- return zoneMonitorThresholds.get(zone).getSingleValuedThresholdMap(varName);
+ public static Map getSingleValuedThresholdMap(
+ String zone, ObConst.VarName varName) {
+ if (varName == VarName.WIND_DIR || varName == VarName.PRIM_SWELL_DIR
+ || varName == VarName.SEC_SWELL_DIR) {
+ return null;
+ }
+ return zoneMonitorThresholds.get(zone).getSingleValuedThresholdMap(
+ varName);
}
-
+
/**
* [Dec 24, 2009, zhao]
- * @param zone the zone ID
- * @param varName enumerated-type variable name
- * @return duel-valued threshold map, or null if the variable
- * name is invalid or if the map contains no mapping for the key
+ *
+ * @param zone
+ * the zone ID
+ * @param varName
+ * enumerated-type variable name
+ * @return duel-valued threshold map, or null if the variable name is
+ * invalid or if the map contains no mapping for the key
*/
- public static Map getDualValuedThresholdMap(String zone, ObConst.VarName varName) {
- if (varName != VarName.WIND_DIR || varName != VarName.PRIM_SWELL_DIR || varName != VarName.SEC_SWELL_DIR ) {
- return null;
- }
- return zoneMonitorThresholds.get(zone).getDualValuedThresholdMap(varName);
+ public static Map getDualValuedThresholdMap(
+ String zone, ObConst.VarName varName) {
+ if (varName != VarName.WIND_DIR || varName != VarName.PRIM_SWELL_DIR
+ || varName != VarName.SEC_SWELL_DIR) {
+ return null;
+ }
+ return zoneMonitorThresholds.get(zone).getDualValuedThresholdMap(
+ varName);
}
}
diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObHourReports.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObHourReports.java
index 83d84ad0d1..08f6f3a262 100644
--- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObHourReports.java
+++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObHourReports.java
@@ -23,7 +23,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import com.raytheon.uf.common.monitor.data.CommonConfig;
import com.raytheon.uf.common.monitor.data.CommonConfig.AppName;
@@ -40,13 +39,14 @@ import com.raytheon.uf.viz.monitor.thresholds.AbstractThresholdMgr;
*
*
* SOFTWARE HISTORY
- * Date Ticket# Engineer Description
+ * Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec. 1, 2009 3424 zhao Initial creation.
* Oct.29, 2012 1297 skorolev Changed HashMap to Map
- * Oct.31 2012 1297 skorolev Cleaned code.
- * Sep 04 2014 3220 skorolev Added updateZones method.
- * Dec 18 2014 3841 skorolev Corrected updateZones method.
+ * Oct.31, 2012 1297 skorolev Cleaned code.
+ * Sep 04, 2014 3220 skorolev Added updateZones method.
+ * Dec 18, 2014 3841 skorolev Corrected updateZones method.
+ * Jan 08, 2015 3220 skorolev Replaced MonitoringArea with areaConfig.
*
*
*
@@ -73,6 +73,9 @@ public class ObHourReports {
*/
private Map hourReports;
+ /**
+ * current threshold manager
+ */
private AbstractThresholdMgr thresholdMgr;
/**
@@ -86,9 +89,8 @@ public class ObHourReports {
this.appName = appName;
this.thresholdMgr = thresholdMgr;
hourReports = new HashMap();
- Map> zoneStationMap = MonitoringArea
- .getPlatformMap();
- for (String zone : zoneStationMap.keySet()) {
+ List zones = thresholdMgr.getAreaConfigMgr().getAreaList();
+ for (String zone : zones) {
hourReports.put(zone, new ObZoneHourReports(nominalTime, zone,
appName, thresholdMgr));
}
@@ -101,7 +103,8 @@ public class ObHourReports {
*/
public void addReport(ObReport report) {
String station = report.getPlatformId();
- List zones = MonitoringArea.getZoneIds(station);
+ List zones = thresholdMgr.getAreaConfigMgr()
+ .getAreaByStationId(station);
if (zones.size() == 0) {
statusHandler
.error("Error: station: "
@@ -123,6 +126,8 @@ public class ObHourReports {
}
/**
+ * Gets HourReports
+ *
* @return hourReports
*/
public Map getHourReports() {
@@ -186,8 +191,8 @@ public class ObHourReports {
}
/**
- * Returns the ObZoneHourReports object of a caller-specified zone. If such
- * object not available, returns null.
+ * Gets ObZoneHourReports Returns the ObZoneHourReports object of a
+ * caller-specified zone. If such object not available, returns null.
*
* @param zone
* @return hour reports
@@ -200,6 +205,8 @@ public class ObHourReports {
}
/**
+ * Gets NominalTime
+ *
* @return nominalTime
*/
public Date getNominalTime() {
@@ -207,6 +214,8 @@ public class ObHourReports {
}
/**
+ * Gets AppName
+ *
* @return appName
*/
public CommonConfig.AppName getAppName() {
@@ -217,10 +226,10 @@ public class ObHourReports {
* Updates zones in the Hour Reports
*/
public void updateZones() {
- Map> zoneStationMap = MonitoringArea
- .getPlatformMap();
// Updated list of zones
- Set updtZones = zoneStationMap.keySet();
+ List updtZones = thresholdMgr.getAreaConfigMgr().getAreaList();
+ // remove zones
+ hourReports.keySet().retainAll(updtZones);
// add zones
for (String zone : updtZones) {
if (!hourReports.keySet().contains(zone)) {
@@ -228,12 +237,14 @@ public class ObHourReports {
appName, thresholdMgr));
}
}
- // remove zones
- hourReports.keySet().retainAll(updtZones);
// add and(or) remove stations
for (String zone : updtZones) {
// Updated list of stations in this zone
- List updtStns = zoneStationMap.get(zone);
+ List updtStns = thresholdMgr.getAreaConfigMgr()
+ .getAreaStations(zone);
+ // remove stations
+ hourReports.get(zone).getZoneHourReports().keySet()
+ .retainAll(updtStns);
// add stations
for (String stn : updtStns) {
if (!hourReports.get(zone).getZoneHourReports()
@@ -246,9 +257,8 @@ public class ObHourReports {
stn, appName, thresholdMgr));
}
}
- // remove stations
- hourReports.get(zone).getZoneHourReports().keySet()
- .retainAll(updtStns);
+ // update hourReports for current zone
+ hourReports.get(zone).getZoneHourReports();
}
}
}
diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObMultiHrsReports.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObMultiHrsReports.java
old mode 100644
new mode 100755
index 9ab69e8dc1..92c08e228d
--- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObMultiHrsReports.java
+++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObMultiHrsReports.java
@@ -24,11 +24,13 @@ import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
+import com.raytheon.uf.common.monitor.config.FSSObsMonitorConfigurationManager;
import com.raytheon.uf.common.monitor.data.CommonConfig;
import com.raytheon.uf.common.monitor.data.CommonConfig.AppName;
import com.raytheon.uf.common.monitor.data.ObConst;
@@ -53,7 +55,8 @@ import com.raytheon.uf.viz.monitor.thresholds.AbstractThresholdMgr;
* Oct.31, 2012 1297 skorolev Clean code.
* Jan. 29, 2013 15654 zhao add Wind Chill calculation for SNOW
* Sep 04, 2014 3220 skorolev Updated getStationTableData method.
- *
+ * Jan 08, 2015 3220 skorolev Replaced MonitoringArea with cfgMgr.
+ *
*
*
* @author zhao
@@ -151,13 +154,15 @@ public class ObMultiHrsReports {
/**
* DR15654: set Wind Chill for SNOW
*/
- if ( appName == AppName.SNOW ) {
- if ( report.getTemperature() != ObConst.MISSING && report.getWindSpeed() != ObConst.MISSING ) {
- report.setWindChill(calcWindChill( report.getTemperature(), report.getWindSpeed() ));
+ if (appName == AppName.SNOW) {
+ if (report.getTemperature() != ObConst.MISSING
+ && report.getWindSpeed() != ObConst.MISSING) {
+ report.setWindChill(calcWindChill(report.getTemperature(),
+ report.getWindSpeed()));
}
-
+
}
-
+
if (multiHrsReports.containsKey(nominalTime)) {
multiHrsReports.get(nominalTime).addReport(report);
} else {
@@ -173,28 +178,28 @@ public class ObMultiHrsReports {
}
}
- /**
- * DR 15654:
- * Wind Chill calculation formula based on
- * http://www.nws.noaa.gov/om/windchill/
- * as of Jan. 29, 2013
- *
- * @param temperature in degree F
- * @param windSpeed in knots
- * @return wind chill in degree F
- */
- private float calcWindChill(float temp, float windSpd) {
- if ( temp > 50.0 || windSpd < 3.0 ) {
- return ObConst.MISSING;
- }
- /**
- * 1 knots = 1.15078 mph
- */
- float spd = (float) Math.pow(1.15078*windSpd, 0.16);
- return 35.74f + 0.6215f*temp - 35.75f*spd + 0.4275f*temp*spd;
- }
+ /**
+ * DR 15654: Wind Chill calculation formula based on
+ * http://www.nws.noaa.gov/om/windchill/ as of Jan. 29, 2013
+ *
+ * @param temp
+ * in degree F
+ * @param windSpd
+ * in knots
+ * @return wind chill in degree F
+ */
+ private float calcWindChill(float temp, float windSpd) {
+ if (temp > 50.0 || windSpd < 3.0) {
+ return ObConst.MISSING;
+ }
+ /**
+ * 1 knots = 1.15078 mph
+ */
+ float spd = (float) Math.pow(1.15078 * windSpd, 0.16);
+ return 35.74f + 0.6215f * temp - 35.75f * spd + 0.4275f * temp * spd;
+ }
- /**
+ /**
* Returns a zone TableData object of the latest nominal time. If no data
* available (the map is empty), returns an empty zone TableData object
* (table cells filled with "N/A").
@@ -252,6 +257,9 @@ public class ObMultiHrsReports {
/**
* Returns the station TableData object for the latest nominal time. If no
* data available, an empty/default station TableData object is returned
+ *
+ * @param zone
+ * @return
*/
public TableData getStationTableData(String zone) {
if (multiHrsReports.isEmpty()) {
@@ -264,9 +272,13 @@ public class ObMultiHrsReports {
* Returns a station TableData object for a caller-specified nominal-time
* and zone ID. If no data available, an empty/default station TableData
* object is returned.
+ *
+ * @param nominalTime
+ * @param zone
+ * @return
*/
public TableData getStationTableData(Date nominalTime, String zone) {
- if(zone.equals("")){
+ if (zone.equals("")) {
return this.getEmptyZoneTableData();
}
if (nominalTime == null) {
@@ -296,6 +308,7 @@ public class ObMultiHrsReports {
* @param zone
* @param Station
* @param varName
+ * @param productName
* @return ObTrendDataSet object, or null if no data available
*/
public ObTrendDataSet getTrendDataSet(String zone, String station,
@@ -373,12 +386,15 @@ public class ObMultiHrsReports {
}
/**
+ * Gets Histogram Table Data
*
+ * @param zone
+ * : current zone
* @param station
- * station ID
+ * : station ID
* @param obsType
- * ObsHistType
- * @return TableData object for obs history table
+ * : ObsHistType
+ * @return
*/
public TableData getHistTableData(String zone, String station,
ObsHistType obsType) {
@@ -467,17 +483,17 @@ public class ObMultiHrsReports {
}
/**
- * Returns a SortedMap object
+ * Gets MultiHrsReports
*
- * @return multiHrsReports
+ * @return SortedMap object
*/
public SortedMap getMultiHrsReports() {
return multiHrsReports;
}
/**
- * Returns a SortedMap object (key is nominal time, value is zone TableData
- * object)
+ * Gets MultiHrsTableData Returns a SortedMap object (key is nominal time,
+ * value is zone TableData object)
*
* @return
*/
@@ -500,8 +516,8 @@ public class ObMultiHrsReports {
}
/**
- * Returns the latest nominal time if the map is not empty; otherwise,
- * returns the nominal time of the present date-time
+ * Gets the Latest NominalTime Returns the latest nominal time if the map is
+ * not empty; otherwise, returns the nominal time of the present date-time
*
* @return
*/
@@ -517,17 +533,17 @@ public class ObMultiHrsReports {
}
/**
- * Returns a set of nominal times
+ * Gets Nominal Times
*
- * @return
+ * @return a set of nominal times
*/
public Set getNominalTimes() {
return multiHrsReports.keySet();
}
/**
- * Returns the ObHourReports object of the latest nominal time. If no data
- * available, returns an empty ObHourReports object.
+ * Gets ObHourReports Returns the ObHourReports object of the latest nominal
+ * time. If no data available, returns an empty ObHourReports object.
*
* @return
*/
@@ -540,8 +556,9 @@ public class ObMultiHrsReports {
}
/**
- * Returns an ObHourReports object of a caller-specified nominal time. If no
- * data available, returns an empty ObHourReports object.
+ * Gets ObHourReports Returns an ObHourReports object of a caller-specified
+ * nominal time. If no data available, returns an empty ObHourReports
+ * object.
*
* @param nominalTime
* @return
@@ -574,6 +591,7 @@ public class ObMultiHrsReports {
}
/**
+ * Gets Threshold Manager
*
* @return the threshold manager
*/
@@ -591,6 +609,7 @@ public class ObMultiHrsReports {
}
/**
+ * Gets map of types for ALG cell
*
* @return fogAlgCellType
*/
@@ -603,7 +622,13 @@ public class ObMultiHrsReports {
*/
private void initFogAlgCellType() {
fogAlgCellType = new HashMap();
- Set zones = MonitoringArea.getPlatformMap().keySet();
+ FSSObsMonitorConfigurationManager cfgMgr = null;
+ if (appName.equals(CommonConfig.AppName.FOG)) {
+ cfgMgr = FSSObsMonitorConfigurationManager.getFogObsManager();
+ } else if (appName.equals(CommonConfig.AppName.SAFESEAS)) {
+ cfgMgr = FSSObsMonitorConfigurationManager.getSsObsManager();
+ }
+ List zones = cfgMgr.getAreaList();
Iterator itr = zones.iterator();
while (itr.hasNext()) {
fogAlgCellType.put(itr.next(), CellType.NotAvailable);
diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObZoneHourReports.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObZoneHourReports.java
old mode 100644
new mode 100755
index 2eab2d8cc6..51a117f059
--- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObZoneHourReports.java
+++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/ObZoneHourReports.java
@@ -21,18 +21,22 @@ package com.raytheon.uf.viz.monitor.data;
import java.util.Date;
import java.util.HashMap;
+import java.util.List;
import com.raytheon.uf.common.monitor.data.CommonConfig;
import com.raytheon.uf.common.monitor.data.ObConst;
import com.raytheon.uf.common.monitor.data.ObConst.DataUsageKey;
+import com.raytheon.uf.common.status.IUFStatusHandler;
+import com.raytheon.uf.common.status.UFStatus;
+import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.monitor.config.CommonTableConfig.CellType;
import com.raytheon.uf.viz.monitor.thresholds.AbstractThresholdMgr;
import com.raytheon.uf.viz.monitor.util.MonitorConfigConstants;
/**
- * This class is a container of ObStnHourReports objects for
- * caller-specified zone and nominal date-time
- * (this class corresponds to the RcZoneHourReports c++ class in AWIPS 1)
+ * This class is a container of ObStnHourReports objects for caller-specified
+ * zone and nominal date-time (this class corresponds to the RcZoneHourReports
+ * c++ class in AWIPS 1)
*
*
*
@@ -40,7 +44,8 @@ import com.raytheon.uf.viz.monitor.util.MonitorConfigConstants;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Dec. 1, 2009 3424 zhao Initial creation.
- * Jan 25, 2010 4281 zhao Modified updateWorstValuesFog method
+ * Jan 25, 2010 4281 zhao Modified updateWorstValuesFog method.
+ * Jan 08, 2015 3220 skorolev Replaced MonitoringArea with areaConfig.
*
*
*
@@ -49,374 +54,645 @@ import com.raytheon.uf.viz.monitor.util.MonitorConfigConstants;
*/
public class ObZoneHourReports {
-
- /**
- * the nominal time and zone ID of this ObZoneHourReports object
- */
- private Date nominalTime;
- private String zone;
-
- /**
- * Thresholds manager
- */
- private AbstractThresholdMgr thresholdMgr;
-
- /**
- * application name (snow, fog, safeseas, etc)
- */
- private CommonConfig.AppName appName;
-
- /**
- * key is station id, value is ObStnHourReports object
- */
- private HashMap zoneHourReports;
-
- /**
- * this object stores worst values of the observation variables
- * reported during this nominal hour for this zone
- */
- private ObReport worstValues;
-
- public ObZoneHourReports(Date nominalTime, String zone, CommonConfig.AppName appName, AbstractThresholdMgr thresholdMgr) {
- this.nominalTime = nominalTime;
- this.zone = zone;
- this.appName = appName;
- this.thresholdMgr =thresholdMgr;
- zoneHourReports = new HashMap();
- for ( String station : MonitoringArea.getPlatformMap().get(zone) ) {
- zoneHourReports.put(station, new ObStnHourReports(nominalTime, zone, station, appName, thresholdMgr));
- }
- InitWorstValues();
- }
-
- private void InitWorstValues() {
- worstValues = new ObReport();
- worstValues.setZoneId(zone); // the ObReport's init() sets "zone id" to "" !!!
- }
- /**
- * @param xmlKey : XML key of a directional obs variable
- * @param dirCurrent : the current worst value
- * @param dirNew : the value contained in a new obs report
- * @return : the value of worse threat level
- */
- private float worseDirection(String xmlKeyFrom, String xmlKeyTo, float dirCurrent, float dirNew) {
- /**
- * decide which one of the two wind directions is worse
- * by comparing their corresponding threat levels
- */
- if ( dirNew == ObConst.MISSING ) {
- return dirCurrent;
- }
-
- if ( dirCurrent == ObConst.MISSING ) {
- return dirNew;
- }
-
- CellType cellTypeCurrent = thresholdMgr.getDirectionalThresholdValueCellType(DataUsageKey.DISPLAY, zone, xmlKeyFrom, xmlKeyTo, dirCurrent);
-
- if ( cellTypeCurrent == CellType.R ) {
- /**
- * already worst threat level
- */
- return dirCurrent;
- }
-
- CellType cellTypeNew = thresholdMgr.getDirectionalThresholdValueCellType(DataUsageKey.DISPLAY, zone, xmlKeyFrom, xmlKeyTo, dirNew);
-
- /**
- * CellType is enumerated in the order R, Y, G, N/A, ...
- */
- if ( cellTypeNew.compareTo(cellTypeCurrent) < 0 ) {
- /**
- * dirNew corresponds to a higher threat level
- */
- return dirNew;
- }
-
- return dirCurrent;
- }
+ private final IUFStatusHandler statusHandler = UFStatus
+ .getHandler(ObZoneHourReports.class);
- public void addReport(ObReport report) {
- String station = report.getPlatformId();
- if ( zoneHourReports.containsKey(station) ) {
- zoneHourReports.get(station).addReport(report);
- } else {
- System.out.println("Error: unrecognized station ID: " + station + " (app = " + appName +")");
- }
- //updateWorstValues(report);
- }
-
- public TableData getStationTableData() {
- TableData tblData = new TableData(appName);
- for ( String station : zoneHourReports.keySet() ) {
- tblData.addTableRowData(this.getObStnHourReports(station).getStationTableRowData());
- }
- return tblData;
- }
+ /** the nominal time and zone ID of this ObZoneHourReports object */
+ private Date nominalTime;
- /**
- * Returns a row of a zone table based on all reports within the nominal hour
- * for the specified zone.
- * If no data available, an empty/default row of table data is returned.
- * @return
- */
- public TableRowData getZoneTableRowData() {
- TableRowData tblRowData = null;
-
- if ( appName==CommonConfig.AppName.FOG ) {
- updateFogWorstValues();
- tblRowData = TableUtil.getFogTableRowData(zone, zone, worstValues, thresholdMgr, CellType.NotAvailable);
- } else if ( appName==CommonConfig.AppName.SAFESEAS ) {
- updateSafeseasWorstValues();
- tblRowData = TableUtil.getSafeseasTableRowData(zone, zone, worstValues, thresholdMgr, CellType.NotAvailable);
- } else if ( appName==CommonConfig.AppName.SNOW ) {
- updateSnowWorstValues();
- tblRowData = TableUtil.getSnowTableRowData(zone, zone, worstValues, thresholdMgr);
- } else {
- System.out.println("unrecognized appName: " + appName);
- }
- return tblRowData;
- }
-
- public TableRowData getFogZoneTableRowData(CellType algCellType) {
- updateFogWorstValues();
- return TableUtil.getFogTableRowData(zone, zone, worstValues, thresholdMgr, algCellType);
- }
-
- public TableRowData getSSZoneTableRowData(CellType algCellType) {
- updateSafeseasWorstValues();
- return TableUtil.getSafeseasTableRowData(zone, zone, worstValues, thresholdMgr, algCellType);
- }
+ /** Monitoring area */
+ private String zone;
- private void updateFogWorstValues() {
- if ( zoneHourReports.isEmpty() ) {
- return;
- }
- InitWorstValues();
- for ( String station : zoneHourReports.keySet() ) {
- ObReport report = zoneHourReports.get(station).getLatestObReport();
- if ( report != null ) {
- if ( report.getVisibility() != ObConst.MISSING ) {
- worstValues.setVisibility(worstValues.getVisibility()==ObConst.MISSING?report.getVisibility():Math.min(worstValues.getVisibility(),report.getVisibility()));
- }
-
- worstValues.setPresentWx(worstValues.getPresentWx()+report.getPresentWx());
-
- if ( report.getCeiling() != ObConst.MISSING ) {
- worstValues.setCeiling(worstValues.getCeiling()==ObConst.MISSING?report.getCeiling():Math.min(worstValues.getCeiling(),report.getCeiling()));
- }
-
- if ( report.getWindDir() != ObConst.MISSING ) {
- worstValues.setWindDir(worseDirection(MonitorConfigConstants.FogDisplay.FOG_DISP_WIND_DIR_FROM.getXmlKey(), MonitorConfigConstants.FogDisplay.FOG_DISP_WIND_DIR_TO.getXmlKey(), worstValues.getWindDir(),report.getWindDir()));
- }
-
- if ( report.getWindSpeed() != ObConst.MISSING ) {
- worstValues.setWindSpeed(worstValues.getWindSpeed()==ObConst.MISSING?report.getWindSpeed():Math.max(worstValues.getWindSpeed(),report.getWindSpeed()));
- }
-
- if ( report.getMaxWindSpeed() != ObConst.MISSING ) {
- worstValues.setMaxWindSpeed(worstValues.getMaxWindSpeed()==ObConst.MISSING?report.getMaxWindSpeed():Math.max(worstValues.getMaxWindSpeed(),report.getMaxWindSpeed()));
- }
-
- if ( report.getWindGust() != ObConst.MISSING ) {
- worstValues.setWindGust(worstValues.getWindGust()==ObConst.MISSING?report.getWindGust():Math.max(worstValues.getWindGust(),report.getWindGust()));
- }
-
- if ( report.getTemperature() != ObConst.MISSING ) {
- worstValues.setTemperature(worstValues.getTemperature()==ObConst.MISSING?report.getTemperature():Math.max(worstValues.getTemperature(),report.getTemperature()));
- }
-
- if ( report.getDewpoint() != ObConst.MISSING ) {
- worstValues.setDewpoint(worstValues.getDewpoint()==ObConst.MISSING?report.getDewpoint():Math.max(worstValues.getDewpoint(),report.getDewpoint()));
- }
-
- if ( report.getDewpointDepr() != ObConst.MISSING ) {
- worstValues.setDewpointDepr(worstValues.getDewpointDepr()==ObConst.MISSING?report.getDewpointDepr():Math.min(worstValues.getDewpointDepr(),report.getDewpointDepr()));
- }
-
- if ( report.getRelativeHumidity() != ObConst.MISSING ) {
- worstValues.setRelativeHumidity(worstValues.getRelativeHumidity()==ObConst.MISSING?report.getRelativeHumidity():Math.max(worstValues.getRelativeHumidity(),report.getRelativeHumidity()));
- }
- }
- }
- }
+ /** Thresholds manager */
+ private AbstractThresholdMgr thresholdMgr;
- private void updateSnowWorstValues() {
- if ( zoneHourReports.isEmpty() ) {
- return;
- }
- InitWorstValues();
- for ( String station : zoneHourReports.keySet() ) {
- ObReport report = zoneHourReports.get(station).getLatestObReport();
- if ( report != null ) {
- worstValues.setPresentWx(worstValues.getPresentWx()+report.getPresentWx());
-
- if ( report.getWindDir() != ObConst.MISSING ) {
- worstValues.setWindDir(worseDirection(MonitorConfigConstants.SnowDisplay.SNOW_DISP_WIND_DIR_FROM.getXmlKey(), MonitorConfigConstants.SnowDisplay.SNOW_DISP_WIND_DIR_TO.getXmlKey(), worstValues.getWindDir(),report.getWindDir()));
- }
-
- if ( report.getWindSpeed() != ObConst.MISSING ) {
- worstValues.setWindSpeed(worstValues.getWindSpeed()==ObConst.MISSING?report.getWindSpeed():Math.max(worstValues.getWindSpeed(),report.getWindSpeed()));
- }
-
- if ( report.getMaxWindSpeed() != ObConst.MISSING ) {
- worstValues.setMaxWindSpeed(worstValues.getMaxWindSpeed()==ObConst.MISSING?report.getMaxWindSpeed():Math.max(worstValues.getMaxWindSpeed(),report.getMaxWindSpeed()));
- }
-
- if ( report.getWindGust() != ObConst.MISSING ) {
- worstValues.setWindGust(worstValues.getWindGust()==ObConst.MISSING?report.getWindGust():Math.max(worstValues.getWindGust(),report.getWindGust()));
- }
-
- if ( report.getTemperature() != ObConst.MISSING ) {
- worstValues.setTemperature(worstValues.getTemperature()==ObConst.MISSING?report.getTemperature():Math.min(worstValues.getTemperature(),report.getTemperature()));
- }
-
- if ( report.getDewpoint() != ObConst.MISSING ) {
- worstValues.setDewpoint(worstValues.getDewpoint()==ObConst.MISSING?report.getDewpoint():Math.min(worstValues.getDewpoint(),report.getDewpoint()));
- }
-
- if ( report.getVisibility() != ObConst.MISSING ) {
- worstValues.setVisibility(worstValues.getVisibility()==ObConst.MISSING?report.getVisibility():Math.min(worstValues.getVisibility(),report.getVisibility()));
- }
-
- if ( report.getSeaLevelPress() != ObConst.MISSING ) {
- worstValues.setSeaLevelPress(worstValues.getSeaLevelPress()==ObConst.MISSING?report.getSeaLevelPress():Math.min(worstValues.getSeaLevelPress(),report.getSeaLevelPress()));
- }
-
- if ( report.getWindChill() != ObConst.MISSING ) {
- worstValues.setWindChill(worstValues.getWindChill()==ObConst.MISSING?report.getWindChill():Math.min(worstValues.getWindChill(),report.getWindChill()));
- }
-
- if ( report.getFrostbiteTime() != ObConst.MISSING ) {
- worstValues.setFrostbiteTime(worstValues.getFrostbiteTime()==ObConst.MISSING?report.getFrostbiteTime():Math.min(worstValues.getFrostbiteTime(),report.getFrostbiteTime()));
- }
-
- if ( report.getHourlyPrecip() != ObConst.MISSING ) {
- worstValues.setHourlyPrecip(worstValues.getHourlyPrecip()==ObConst.MISSING?report.getHourlyPrecip():Math.max(worstValues.getHourlyPrecip(),report.getHourlyPrecip()));
- }
-
- if ( report.getSnowDepth() != ObConst.MISSING ) {
- worstValues.setSnowDepth(worstValues.getSnowDepth()==ObConst.MISSING?report.getSnowDepth():Math.max(worstValues.getSnowDepth(),report.getSnowDepth()));
- }
-
- if ( report.getSnincrHourly() != ObConst.MISSING ) {
- worstValues.setSnincrHourly(worstValues.getSnincrHourly()==ObConst.MISSING?report.getSnincrHourly():Math.max(worstValues.getSnincrHourly(),report.getSnincrHourly()));
- }
-
- if ( report.getSnincrTotal() != ObConst.MISSING ) {
- worstValues.setSnincrTotal(worstValues.getSnincrTotal()==ObConst.MISSING?report.getSnincrTotal():Math.max(worstValues.getSnincrTotal(),report.getSnincrTotal()));
- }
- }
- }
- }
+ /** application name (snow, fog, safeseas, etc) */
+ private CommonConfig.AppName appName;
- private void updateSafeseasWorstValues() {
- if ( zoneHourReports.isEmpty() ) {
- return;
- }
- InitWorstValues();
- for ( String station : zoneHourReports.keySet() ) {
- ObReport report = zoneHourReports.get(station).getLatestObReport();
- if ( report != null ) {
- if ( report.getWindDir() != ObConst.MISSING ) {
- worstValues.setWindDir(worstValues.getWindDir()==ObConst.MISSING?report.getWindDir():worseDirection(MonitorConfigConstants.SafeSeasDisplay.SS_DISP_WIND_DIR_FROM.getXmlKey(), MonitorConfigConstants.SafeSeasDisplay.SS_DISP_WIND_DIR_TO.getXmlKey(), worstValues.getWindDir(),report.getWindDir()));
- }
-
- if ( report.getWindSpeed() != ObConst.MISSING ) {
- worstValues.setWindSpeed(worstValues.getWindSpeed()==ObConst.MISSING?report.getWindSpeed():Math.max(worstValues.getWindSpeed(),report.getWindSpeed()));
- }
-
- if ( report.getMaxWindSpeed() != ObConst.MISSING ) {
- worstValues.setMaxWindSpeed(worstValues.getMaxWindSpeed()==ObConst.MISSING?report.getMaxWindSpeed():Math.max(worstValues.getMaxWindSpeed(),report.getMaxWindSpeed()));
- }
-
- if ( report.getWindGust() != ObConst.MISSING ) {
- worstValues.setWindGust(worstValues.getWindGust()==ObConst.MISSING?report.getWindGust():Math.max(worstValues.getWindGust(),report.getWindGust()));
- }
-
- if ( report.getVisibility() != ObConst.MISSING ) {
- worstValues.setVisibility(worstValues.getVisibility()==ObConst.MISSING?report.getVisibility():Math.min(worstValues.getVisibility(),report.getVisibility()));
- }
-
- if ( report.getTemperature() != ObConst.MISSING ) {
- worstValues.setTemperature(worstValues.getTemperature()==ObConst.MISSING?report.getTemperature():Math.max(worstValues.getTemperature(),report.getTemperature()));
- }
-
- if ( report.getDewpoint() != ObConst.MISSING ) {
- worstValues.setDewpoint(worstValues.getDewpoint()==ObConst.MISSING?report.getDewpoint():Math.max(worstValues.getDewpoint(),report.getDewpoint()));
- }
-
- if ( report.getSeaLevelPress() != ObConst.MISSING ) {
- worstValues.setSeaLevelPress(worstValues.getSeaLevelPress()==ObConst.MISSING?report.getSeaLevelPress():Math.min(worstValues.getSeaLevelPress(),report.getSeaLevelPress()));
- }
-
- if ( report.getSeaSurfaceTemp() != ObConst.MISSING ) {
- worstValues.setSeaSurfaceTemp(worstValues.getSeaSurfaceTemp()==ObConst.MISSING?report.getSeaSurfaceTemp():Math.max(worstValues.getSeaSurfaceTemp(),report.getSeaSurfaceTemp()));
- }
-
- if ( report.getHighResWaveHeight() != ObConst.MISSING ) {
- worstValues.setHighResWaveHeight(worstValues.getHighResWaveHeight()==ObConst.MISSING?report.getHighResWaveHeight():Math.max(worstValues.getHighResWaveHeight(),report.getHighResWaveHeight()));
- }
-
- if ( report.getWaveSteepness() != ObConst.MISSING ) {
- worstValues.setWaveSteepness(worstValues.getWaveSteepness()==ObConst.MISSING?report.getWaveSteepness():Math.max(worstValues.getWaveSteepness(),report.getWaveSteepness()));
- }
-
- if ( report.getPSwellHeight() != ObConst.MISSING ) {
- worstValues.setPSwellHeight(worstValues.getPSwellHeight()==ObConst.MISSING?report.getPSwellHeight():Math.max(worstValues.getPSwellHeight(),report.getPSwellHeight()));
- }
-
- if ( report.getPSwellPeriod() != ObConst.MISSING ) {
- worstValues.setPSwellPeriod(worstValues.getPSwellPeriod()==ObConst.MISSING?report.getPSwellPeriod():Math.max(worstValues.getPSwellPeriod(),report.getPSwellPeriod()));
- }
-
- if ( report.getPSwellDir() != ObConst.MISSING ) {
- worstValues.setPSwellDir(worstValues.getPSwellDir()==ObConst.MISSING?report.getPSwellDir():worseDirection(MonitorConfigConstants.SafeSeasDisplay.SS_DISP_SWELL_PRIM_DIR_FROM.getXmlKey(), MonitorConfigConstants.SafeSeasDisplay.SS_DISP_SWELL_PRIM_DIR_TO.getXmlKey(), worstValues.getPSwellDir(),report.getPSwellDir()));
- }
-
- if ( report.getSSwellHeight() != ObConst.MISSING ) {
- worstValues.setSSwellHeight(worstValues.getSSwellHeight()==ObConst.MISSING?report.getSSwellHeight():Math.max(worstValues.getSSwellHeight(),report.getSSwellHeight()));
- }
-
- if ( report.getSSwellPeriod() != ObConst.MISSING ) {
- worstValues.setSSwellPeriod(worstValues.getSSwellPeriod()==ObConst.MISSING?report.getSSwellPeriod():Math.max(worstValues.getSSwellPeriod(),report.getSSwellPeriod()));
- }
-
- if ( report.getSSwellDir() != ObConst.MISSING ) {
- worstValues.setSSwellDir(worstValues.getSSwellDir()==ObConst.MISSING?report.getSSwellDir():worseDirection(MonitorConfigConstants.SafeSeasDisplay.SS_DISP_SWELL_SEC_DIR_FROM.getXmlKey(), MonitorConfigConstants.SafeSeasDisplay.SS_DISP_SWELL_SEC_DIR_TO.getXmlKey(), worstValues.getSSwellDir(),report.getSSwellDir()));
- }
- }
- }
- }
+ /** key is station id, value is ObStnHourReports object */
+ private HashMap zoneHourReports;
- /**
- * Returns the ObStnHourReports object of a caller-specified station.
- * If such object not available, returns null.
- * @param station
- * @return
- */
- public ObStnHourReports getObStnHourReports(String station) {
- if ( !zoneHourReports.containsKey(station) ) {
- return null;
- }
- return zoneHourReports.get(station);
- }
-
- public HashMap getZoneHourReports() {
- return zoneHourReports;
- }
-
- public Date getNominalTime() {
- return nominalTime;
- }
-
- public String getZone() {
- return zone;
- }
-
- public CommonConfig.AppName getAppName() {
- return appName;
- }
+ /**
+ * this object stores worst values of the observation variables reported
+ * during this nominal hour for this zone
+ */
+ private ObReport worstValues;
+
+ /**
+ * Constructor
+ *
+ * @param nominalTime
+ * @param zone
+ * @param appName
+ * @param thresholdMgr
+ */
+ public ObZoneHourReports(Date nominalTime, String zone,
+ CommonConfig.AppName appName, AbstractThresholdMgr thresholdMgr) {
+ this.nominalTime = nominalTime;
+ this.zone = zone;
+ this.appName = appName;
+ this.thresholdMgr = thresholdMgr;
+ zoneHourReports = new HashMap();
+ List stations = thresholdMgr.getAreaConfigMgr()
+ .getAreaStations(zone);
+ for (String station : stations) {
+ zoneHourReports.put(station, new ObStnHourReports(nominalTime,
+ zone, station, appName, thresholdMgr));
+ }
+ InitWorstValues();
+ }
+
+ /**
+ * Initiates the worst values.
+ */
+ private void InitWorstValues() {
+ worstValues = new ObReport();
+ worstValues.setZoneId(zone);
+ // the ObReport's init() sets "zone id" to
+ // "" !!!
+ }
+
+ /**
+ * The worst direction
+ *
+ * @param xmlKeyFrom
+ * : XML key of a directional obs from variable
+ * @param xmlKeyTo
+ * : XML key of a directional obs to variable
+ * @param dirCurrent
+ * : the current worst value
+ * @param dirNew
+ * : the value contained in a new obs report
+ * @return : the value of worse threat level
+ */
+ private float worseDirection(String xmlKeyFrom, String xmlKeyTo,
+ float dirCurrent, float dirNew) {
+ /**
+ * decide which one of the two wind directions is worse by comparing
+ * their corresponding threat levels
+ */
+ if (dirNew == ObConst.MISSING) {
+ return dirCurrent;
+ }
+
+ if (dirCurrent == ObConst.MISSING) {
+ return dirNew;
+ }
+
+ CellType cellTypeCurrent = thresholdMgr
+ .getDirectionalThresholdValueCellType(DataUsageKey.DISPLAY,
+ zone, xmlKeyFrom, xmlKeyTo, dirCurrent);
+
+ if (cellTypeCurrent == CellType.R) {
+ /**
+ * already worst threat level
+ */
+ return dirCurrent;
+ }
+
+ CellType cellTypeNew = thresholdMgr
+ .getDirectionalThresholdValueCellType(DataUsageKey.DISPLAY,
+ zone, xmlKeyFrom, xmlKeyTo, dirNew);
+
+ /**
+ * CellType is enumerated in the order R, Y, G, N/A, ...
+ */
+ if (cellTypeNew.compareTo(cellTypeCurrent) < 0) {
+ /**
+ * dirNew corresponds to a higher threat level
+ */
+ return dirNew;
+ }
+
+ return dirCurrent;
+ }
+
+ /**
+ * Adds report
+ *
+ * @param report
+ */
+ public void addReport(ObReport report) {
+ String station = report.getPlatformId();
+ if (zoneHourReports.containsKey(station)) {
+ zoneHourReports.get(station).addReport(report);
+ } else {
+ statusHandler.handle(Priority.ERROR, "Unrecognized station ID: "
+ + station + " (app = " + appName + ")");
+ }
+ }
+
+ /**
+ * Gets StationTableData
+ *
+ * @return
+ */
+ public TableData getStationTableData() {
+ TableData tblData = new TableData(appName);
+ for (String station : zoneHourReports.keySet()) {
+ tblData.addTableRowData(this.getObStnHourReports(station)
+ .getStationTableRowData());
+ }
+ return tblData;
+ }
+
+ /**
+ * Returns a row of a zone table based on all reports within the nominal
+ * hour for the specified zone. If no data available, an empty/default row
+ * of table data is returned.
+ *
+ * @return
+ */
+ public TableRowData getZoneTableRowData() {
+ TableRowData tblRowData = null;
+
+ if (appName == CommonConfig.AppName.FOG) {
+ updateFogWorstValues();
+ tblRowData = TableUtil.getFogTableRowData(zone, zone, worstValues,
+ thresholdMgr, CellType.NotAvailable);
+ } else if (appName == CommonConfig.AppName.SAFESEAS) {
+ updateSafeseasWorstValues();
+ tblRowData = TableUtil.getSafeseasTableRowData(zone, zone,
+ worstValues, thresholdMgr, CellType.NotAvailable);
+ } else if (appName == CommonConfig.AppName.SNOW) {
+ updateSnowWorstValues();
+ tblRowData = TableUtil.getSnowTableRowData(zone, zone, worstValues,
+ thresholdMgr);
+ } else {
+ System.out.println("unrecognized appName: " + appName);
+ }
+ return tblRowData;
+ }
+
+ /**
+ * Gets Fog Zone Table Row Data
+ *
+ * @param algCellType
+ * @return
+ */
+ public TableRowData getFogZoneTableRowData(CellType algCellType) {
+ updateFogWorstValues();
+ return TableUtil.getFogTableRowData(zone, zone, worstValues,
+ thresholdMgr, algCellType);
+ }
+
+ /**
+ * Gets SAFESEAS Zone Table Row Data
+ *
+ * @param algCellType
+ * : Type of ALG cell in the table
+ * @return
+ */
+ public TableRowData getSSZoneTableRowData(CellType algCellType) {
+ updateSafeseasWorstValues();
+ return TableUtil.getSafeseasTableRowData(zone, zone, worstValues,
+ thresholdMgr, algCellType);
+ }
+
+ /**
+ * Updates Fog Worst Values
+ */
+ private void updateFogWorstValues() {
+ if (zoneHourReports.isEmpty()) {
+ return;
+ }
+ InitWorstValues();
+ for (String station : zoneHourReports.keySet()) {
+ ObReport report = zoneHourReports.get(station).getLatestObReport();
+ if (report != null) {
+ if (report.getVisibility() != ObConst.MISSING) {
+ worstValues
+ .setVisibility(worstValues.getVisibility() == ObConst.MISSING ? report
+ .getVisibility() : Math.min(
+ worstValues.getVisibility(),
+ report.getVisibility()));
+ }
+
+ worstValues.setPresentWx(worstValues.getPresentWx()
+ + report.getPresentWx());
+
+ if (report.getCeiling() != ObConst.MISSING) {
+ worstValues
+ .setCeiling(worstValues.getCeiling() == ObConst.MISSING ? report
+ .getCeiling() : Math.min(
+ worstValues.getCeiling(),
+ report.getCeiling()));
+ }
+
+ if (report.getWindDir() != ObConst.MISSING) {
+ worstValues
+ .setWindDir(worseDirection(
+ MonitorConfigConstants.FogDisplay.FOG_DISP_WIND_DIR_FROM
+ .getXmlKey(),
+ MonitorConfigConstants.FogDisplay.FOG_DISP_WIND_DIR_TO
+ .getXmlKey(), worstValues
+ .getWindDir(), report.getWindDir()));
+ }
+
+ if (report.getWindSpeed() != ObConst.MISSING) {
+ worstValues
+ .setWindSpeed(worstValues.getWindSpeed() == ObConst.MISSING ? report
+ .getWindSpeed() : Math.max(
+ worstValues.getWindSpeed(),
+ report.getWindSpeed()));
+ }
+
+ if (report.getMaxWindSpeed() != ObConst.MISSING) {
+ worstValues
+ .setMaxWindSpeed(worstValues.getMaxWindSpeed() == ObConst.MISSING ? report
+ .getMaxWindSpeed() : Math.max(
+ worstValues.getMaxWindSpeed(),
+ report.getMaxWindSpeed()));
+ }
+
+ if (report.getWindGust() != ObConst.MISSING) {
+ worstValues
+ .setWindGust(worstValues.getWindGust() == ObConst.MISSING ? report
+ .getWindGust() : Math.max(
+ worstValues.getWindGust(),
+ report.getWindGust()));
+ }
+
+ if (report.getTemperature() != ObConst.MISSING) {
+ worstValues
+ .setTemperature(worstValues.getTemperature() == ObConst.MISSING ? report
+ .getTemperature() : Math.max(
+ worstValues.getTemperature(),
+ report.getTemperature()));
+ }
+
+ if (report.getDewpoint() != ObConst.MISSING) {
+ worstValues
+ .setDewpoint(worstValues.getDewpoint() == ObConst.MISSING ? report
+ .getDewpoint() : Math.max(
+ worstValues.getDewpoint(),
+ report.getDewpoint()));
+ }
+
+ if (report.getDewpointDepr() != ObConst.MISSING) {
+ worstValues
+ .setDewpointDepr(worstValues.getDewpointDepr() == ObConst.MISSING ? report
+ .getDewpointDepr() : Math.min(
+ worstValues.getDewpointDepr(),
+ report.getDewpointDepr()));
+ }
+
+ if (report.getRelativeHumidity() != ObConst.MISSING) {
+ worstValues.setRelativeHumidity(worstValues
+ .getRelativeHumidity() == ObConst.MISSING ? report
+ .getRelativeHumidity() : Math.max(
+ worstValues.getRelativeHumidity(),
+ report.getRelativeHumidity()));
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates SNOW Worst Values
+ */
+ private void updateSnowWorstValues() {
+ if (zoneHourReports.isEmpty()) {
+ return;
+ }
+ InitWorstValues();
+ for (String station : zoneHourReports.keySet()) {
+ ObReport report = zoneHourReports.get(station).getLatestObReport();
+ if (report != null) {
+ worstValues.setPresentWx(worstValues.getPresentWx()
+ + report.getPresentWx());
+
+ if (report.getWindDir() != ObConst.MISSING) {
+ worstValues
+ .setWindDir(worseDirection(
+ MonitorConfigConstants.SnowDisplay.SNOW_DISP_WIND_DIR_FROM
+ .getXmlKey(),
+ MonitorConfigConstants.SnowDisplay.SNOW_DISP_WIND_DIR_TO
+ .getXmlKey(), worstValues
+ .getWindDir(), report.getWindDir()));
+ }
+
+ if (report.getWindSpeed() != ObConst.MISSING) {
+ worstValues
+ .setWindSpeed(worstValues.getWindSpeed() == ObConst.MISSING ? report
+ .getWindSpeed() : Math.max(
+ worstValues.getWindSpeed(),
+ report.getWindSpeed()));
+ }
+
+ if (report.getMaxWindSpeed() != ObConst.MISSING) {
+ worstValues
+ .setMaxWindSpeed(worstValues.getMaxWindSpeed() == ObConst.MISSING ? report
+ .getMaxWindSpeed() : Math.max(
+ worstValues.getMaxWindSpeed(),
+ report.getMaxWindSpeed()));
+ }
+
+ if (report.getWindGust() != ObConst.MISSING) {
+ worstValues
+ .setWindGust(worstValues.getWindGust() == ObConst.MISSING ? report
+ .getWindGust() : Math.max(
+ worstValues.getWindGust(),
+ report.getWindGust()));
+ }
+
+ if (report.getTemperature() != ObConst.MISSING) {
+ worstValues
+ .setTemperature(worstValues.getTemperature() == ObConst.MISSING ? report
+ .getTemperature() : Math.min(
+ worstValues.getTemperature(),
+ report.getTemperature()));
+ }
+
+ if (report.getDewpoint() != ObConst.MISSING) {
+ worstValues
+ .setDewpoint(worstValues.getDewpoint() == ObConst.MISSING ? report
+ .getDewpoint() : Math.min(
+ worstValues.getDewpoint(),
+ report.getDewpoint()));
+ }
+
+ if (report.getVisibility() != ObConst.MISSING) {
+ worstValues
+ .setVisibility(worstValues.getVisibility() == ObConst.MISSING ? report
+ .getVisibility() : Math.min(
+ worstValues.getVisibility(),
+ report.getVisibility()));
+ }
+
+ if (report.getSeaLevelPress() != ObConst.MISSING) {
+ worstValues
+ .setSeaLevelPress(worstValues.getSeaLevelPress() == ObConst.MISSING ? report
+ .getSeaLevelPress() : Math.min(
+ worstValues.getSeaLevelPress(),
+ report.getSeaLevelPress()));
+ }
+
+ if (report.getWindChill() != ObConst.MISSING) {
+ worstValues
+ .setWindChill(worstValues.getWindChill() == ObConst.MISSING ? report
+ .getWindChill() : Math.min(
+ worstValues.getWindChill(),
+ report.getWindChill()));
+ }
+
+ if (report.getFrostbiteTime() != ObConst.MISSING) {
+ worstValues
+ .setFrostbiteTime(worstValues.getFrostbiteTime() == ObConst.MISSING ? report
+ .getFrostbiteTime() : Math.min(
+ worstValues.getFrostbiteTime(),
+ report.getFrostbiteTime()));
+ }
+
+ if (report.getHourlyPrecip() != ObConst.MISSING) {
+ worstValues
+ .setHourlyPrecip(worstValues.getHourlyPrecip() == ObConst.MISSING ? report
+ .getHourlyPrecip() : Math.max(
+ worstValues.getHourlyPrecip(),
+ report.getHourlyPrecip()));
+ }
+
+ if (report.getSnowDepth() != ObConst.MISSING) {
+ worstValues
+ .setSnowDepth(worstValues.getSnowDepth() == ObConst.MISSING ? report
+ .getSnowDepth() : Math.max(
+ worstValues.getSnowDepth(),
+ report.getSnowDepth()));
+ }
+
+ if (report.getSnincrHourly() != ObConst.MISSING) {
+ worstValues
+ .setSnincrHourly(worstValues.getSnincrHourly() == ObConst.MISSING ? report
+ .getSnincrHourly() : Math.max(
+ worstValues.getSnincrHourly(),
+ report.getSnincrHourly()));
+ }
+
+ if (report.getSnincrTotal() != ObConst.MISSING) {
+ worstValues
+ .setSnincrTotal(worstValues.getSnincrTotal() == ObConst.MISSING ? report
+ .getSnincrTotal() : Math.max(
+ worstValues.getSnincrTotal(),
+ report.getSnincrTotal()));
+ }
+ }
+ }
+ }
+
+ /**
+ * Updates SAFESEAS Worst Values
+ */
+ private void updateSafeseasWorstValues() {
+ if (zoneHourReports.isEmpty()) {
+ return;
+ }
+ InitWorstValues();
+ for (String station : zoneHourReports.keySet()) {
+ ObReport report = zoneHourReports.get(station).getLatestObReport();
+ if (report != null) {
+ if (report.getWindDir() != ObConst.MISSING) {
+ worstValues
+ .setWindDir(worstValues.getWindDir() == ObConst.MISSING ? report
+ .getWindDir()
+ : worseDirection(
+ MonitorConfigConstants.SafeSeasDisplay.SS_DISP_WIND_DIR_FROM
+ .getXmlKey(),
+ MonitorConfigConstants.SafeSeasDisplay.SS_DISP_WIND_DIR_TO
+ .getXmlKey(), worstValues
+ .getWindDir(), report
+ .getWindDir()));
+ }
+
+ if (report.getWindSpeed() != ObConst.MISSING) {
+ worstValues
+ .setWindSpeed(worstValues.getWindSpeed() == ObConst.MISSING ? report
+ .getWindSpeed() : Math.max(
+ worstValues.getWindSpeed(),
+ report.getWindSpeed()));
+ }
+
+ if (report.getMaxWindSpeed() != ObConst.MISSING) {
+ worstValues
+ .setMaxWindSpeed(worstValues.getMaxWindSpeed() == ObConst.MISSING ? report
+ .getMaxWindSpeed() : Math.max(
+ worstValues.getMaxWindSpeed(),
+ report.getMaxWindSpeed()));
+ }
+
+ if (report.getWindGust() != ObConst.MISSING) {
+ worstValues
+ .setWindGust(worstValues.getWindGust() == ObConst.MISSING ? report
+ .getWindGust() : Math.max(
+ worstValues.getWindGust(),
+ report.getWindGust()));
+ }
+
+ if (report.getVisibility() != ObConst.MISSING) {
+ worstValues
+ .setVisibility(worstValues.getVisibility() == ObConst.MISSING ? report
+ .getVisibility() : Math.min(
+ worstValues.getVisibility(),
+ report.getVisibility()));
+ }
+
+ if (report.getTemperature() != ObConst.MISSING) {
+ worstValues
+ .setTemperature(worstValues.getTemperature() == ObConst.MISSING ? report
+ .getTemperature() : Math.max(
+ worstValues.getTemperature(),
+ report.getTemperature()));
+ }
+
+ if (report.getDewpoint() != ObConst.MISSING) {
+ worstValues
+ .setDewpoint(worstValues.getDewpoint() == ObConst.MISSING ? report
+ .getDewpoint() : Math.max(
+ worstValues.getDewpoint(),
+ report.getDewpoint()));
+ }
+
+ if (report.getSeaLevelPress() != ObConst.MISSING) {
+ worstValues
+ .setSeaLevelPress(worstValues.getSeaLevelPress() == ObConst.MISSING ? report
+ .getSeaLevelPress() : Math.min(
+ worstValues.getSeaLevelPress(),
+ report.getSeaLevelPress()));
+ }
+
+ if (report.getSeaSurfaceTemp() != ObConst.MISSING) {
+ worstValues.setSeaSurfaceTemp(worstValues
+ .getSeaSurfaceTemp() == ObConst.MISSING ? report
+ .getSeaSurfaceTemp() : Math.max(
+ worstValues.getSeaSurfaceTemp(),
+ report.getSeaSurfaceTemp()));
+ }
+
+ if (report.getHighResWaveHeight() != ObConst.MISSING) {
+ worstValues.setHighResWaveHeight(worstValues
+ .getHighResWaveHeight() == ObConst.MISSING ? report
+ .getHighResWaveHeight() : Math.max(
+ worstValues.getHighResWaveHeight(),
+ report.getHighResWaveHeight()));
+ }
+
+ if (report.getWaveSteepness() != ObConst.MISSING) {
+ worstValues
+ .setWaveSteepness(worstValues.getWaveSteepness() == ObConst.MISSING ? report
+ .getWaveSteepness() : Math.max(
+ worstValues.getWaveSteepness(),
+ report.getWaveSteepness()));
+ }
+
+ if (report.getPSwellHeight() != ObConst.MISSING) {
+ worstValues
+ .setPSwellHeight(worstValues.getPSwellHeight() == ObConst.MISSING ? report
+ .getPSwellHeight() : Math.max(
+ worstValues.getPSwellHeight(),
+ report.getPSwellHeight()));
+ }
+
+ if (report.getPSwellPeriod() != ObConst.MISSING) {
+ worstValues
+ .setPSwellPeriod(worstValues.getPSwellPeriod() == ObConst.MISSING ? report
+ .getPSwellPeriod() : Math.max(
+ worstValues.getPSwellPeriod(),
+ report.getPSwellPeriod()));
+ }
+
+ if (report.getPSwellDir() != ObConst.MISSING) {
+ worstValues
+ .setPSwellDir(worstValues.getPSwellDir() == ObConst.MISSING ? report
+ .getPSwellDir()
+ : worseDirection(
+ MonitorConfigConstants.SafeSeasDisplay.SS_DISP_SWELL_PRIM_DIR_FROM
+ .getXmlKey(),
+ MonitorConfigConstants.SafeSeasDisplay.SS_DISP_SWELL_PRIM_DIR_TO
+ .getXmlKey(), worstValues
+ .getPSwellDir(), report
+ .getPSwellDir()));
+ }
+
+ if (report.getSSwellHeight() != ObConst.MISSING) {
+ worstValues
+ .setSSwellHeight(worstValues.getSSwellHeight() == ObConst.MISSING ? report
+ .getSSwellHeight() : Math.max(
+ worstValues.getSSwellHeight(),
+ report.getSSwellHeight()));
+ }
+
+ if (report.getSSwellPeriod() != ObConst.MISSING) {
+ worstValues
+ .setSSwellPeriod(worstValues.getSSwellPeriod() == ObConst.MISSING ? report
+ .getSSwellPeriod() : Math.max(
+ worstValues.getSSwellPeriod(),
+ report.getSSwellPeriod()));
+ }
+
+ if (report.getSSwellDir() != ObConst.MISSING) {
+ worstValues
+ .setSSwellDir(worstValues.getSSwellDir() == ObConst.MISSING ? report
+ .getSSwellDir()
+ : worseDirection(
+ MonitorConfigConstants.SafeSeasDisplay.SS_DISP_SWELL_SEC_DIR_FROM
+ .getXmlKey(),
+ MonitorConfigConstants.SafeSeasDisplay.SS_DISP_SWELL_SEC_DIR_TO
+ .getXmlKey(), worstValues
+ .getSSwellDir(), report
+ .getSSwellDir()));
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the ObStnHourReports object of a caller-specified station. If
+ * such object not available, returns null.
+ *
+ * @param station
+ * @return
+ */
+ public ObStnHourReports getObStnHourReports(String station) {
+ if (!zoneHourReports.containsKey(station)) {
+ return null;
+ }
+ return zoneHourReports.get(station);
+ }
+
+ /**
+ * Gets Zone Hour Reports
+ *
+ * @return
+ */
+ public HashMap getZoneHourReports() {
+ return zoneHourReports;
+ }
+
+ /**
+ * Gets Nominal Time
+ *
+ * @return
+ */
+ public Date getNominalTime() {
+ return nominalTime;
+ }
+
+ /**
+ * Gets Zone
+ *
+ * @return
+ */
+ public String getZone() {
+ return zone;
+ }
+
+ /**
+ * Gets AppName
+ *
+ * @return
+ */
+ public CommonConfig.AppName getAppName() {
+ return appName;
+ }
}
diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/TableUtil.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/TableUtil.java
index 9dbfbf0fbd..4d17f1aecb 100644
--- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/TableUtil.java
+++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/data/TableUtil.java
@@ -53,6 +53,7 @@ import com.raytheon.uf.viz.monitor.util.MonitorConfigConstants;
* Feb 28, 2013 14410 zhao Modified getCellTypeForBlizWarn
* May 23, 2014 3086 skorolev Corrected ObsHistType. Cleaned code.
* Nov 21, 2014 3841 skorolev Added coordinates in the hover text for a newly added zones.
+ * Jan 08, 2015 3220 skorolev Corrected code for Fog and SNOW table data.
*
*
*
@@ -113,10 +114,10 @@ public final class TableUtil {
isZone = true;
}
- String hoverText = null;
+ String hoverText = "";
if (isZone) {
AreaIdXML zoneXML = FSSObsMonitorConfigurationManager
- .getSsObsManager().getAreaXml(zone);
+ .getFogObsManager().getAreaXml(zone);
if (zoneXML != null) {
hoverText = getZoneHoverText(zoneXML);
}
@@ -344,7 +345,7 @@ public final class TableUtil {
isZone = true;
}
- String hoverText = null;
+ String hoverText = "";
if (isZone) {
AreaIdXML zoneXML = FSSObsMonitorConfigurationManager
.getSsObsManager().getAreaXml(zone);
@@ -649,10 +650,10 @@ public final class TableUtil {
isZone = true;
}
- String hoverText = null;
+ String hoverText = "";
if (isZone) {
AreaIdXML zoneXML = FSSObsMonitorConfigurationManager
- .getSsObsManager().getAreaXml(zone);
+ .getSnowObsManager().getAreaXml(zone);
if (zoneXML != null) {
hoverText = getZoneHoverText(zoneXML);
}
diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/thresholds/AbstractThresholdMgr.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/thresholds/AbstractThresholdMgr.java
old mode 100644
new mode 100755
index b558dffa73..0cd16240da
--- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/thresholds/AbstractThresholdMgr.java
+++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/thresholds/AbstractThresholdMgr.java
@@ -57,6 +57,7 @@ import com.raytheon.uf.viz.monitor.xml.ThresholdsXML;
* Feb 16, 2011 #7346 zhao added getDirectionalThresholdValueCellType(...)
* Apr 28, 2014 3086 skorolev Updated getAreaConfigMgr method.
* Oct 17, 2014 3220 skorolev Replaced System.out.print with debug statusHandler.
+ * Jan 08, 2015 3220 skorolev Added getAreaConfigMgr.
*
*
*
@@ -71,7 +72,7 @@ public abstract class AbstractThresholdMgr {
/**
* Monitor Area Configuration Manager.
*/
- protected FSSObsMonitorConfigurationManager areaConfigMgr;
+ public FSSObsMonitorConfigurationManager areaConfigMgr;
/**
* Default file name for the FOG display thresholds.
@@ -808,4 +809,13 @@ public abstract class AbstractThresholdMgr {
}
}
}
+
+ /**
+ * Gets current Area configuration manager.
+ *
+ * @return
+ */
+ public FSSObsMonitorConfigurationManager getAreaConfigMgr() {
+ return areaConfigMgr;
+ }
}
diff --git a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ui/dialogs/MonitoringAreaConfigDlg.java b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ui/dialogs/MonitoringAreaConfigDlg.java
index 1a2750ff53..e82e4927b1 100644
--- a/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ui/dialogs/MonitoringAreaConfigDlg.java
+++ b/cave/com.raytheon.uf.viz.monitor/src/com/raytheon/uf/viz/monitor/ui/dialogs/MonitoringAreaConfigDlg.java
@@ -1301,6 +1301,9 @@ public abstract class MonitoringAreaConfigDlg extends CaveSWTDialog implements
* Handles the monitor area list selection.
*/
private void handleMonitorAreaListSelection() {
+ if (monitorAreaList.getSelectionIndex() == -1) {
+ return;
+ }
if (mode == Mode.Zone) {
String zone = monitorAreaList.getItem(monitorAreaList
.getSelectionIndex());
diff --git a/deltaScripts/14.4.1/DR2707/updateLsrTable.sh b/deltaScripts/14.4.1/DR2707/updateLsrTable.sh
index b22dd6c634..5d4882e068 100755
--- a/deltaScripts/14.4.1/DR2707/updateLsrTable.sh
+++ b/deltaScripts/14.4.1/DR2707/updateLsrTable.sh
@@ -14,8 +14,8 @@ STATION_COLUMN='stationid'
LAT_COLUMN='latitude'
LON_COLUMN='longitude'
-CONSTRAINT_NAME='latitude_longitude_officeId_refTime_forecastTime_eventType'
-CONSTRAINT_COLUMNS='latitude, longitude, officeId, refTime, forecastTime, eventType'
+CONSTRAINT_NAME='latitude_longitude_stationId_refTime_forecastTime_eventType'
+CONSTRAINT_COLUMNS='latitude, longitude, stationId, refTime, forecastTime, eventType'
PSQL="/awips2/psql/bin/psql"
diff --git a/edexOsgi/com.raytheon.uf.common.dataplugin.lsr/src/com/raytheon/uf/common/dataplugin/lsr/LocalStormReport.java b/edexOsgi/com.raytheon.uf.common.dataplugin.lsr/src/com/raytheon/uf/common/dataplugin/lsr/LocalStormReport.java
index d826012799..a05b653e9b 100644
--- a/edexOsgi/com.raytheon.uf.common.dataplugin.lsr/src/com/raytheon/uf/common/dataplugin/lsr/LocalStormReport.java
+++ b/edexOsgi/com.raytheon.uf.common.dataplugin.lsr/src/com/raytheon/uf/common/dataplugin/lsr/LocalStormReport.java
@@ -72,6 +72,7 @@ import com.vividsolutions.jts.geom.Geometry;
* Jan 15, 2014 2581 njensen Changed constraint to use officeId instead of stationId
* Jan 30, 2014 2581 njensen Added dataURI column back in
* Sep 16, 2014 2707 bclement removed dataURI column, event type now string, added event units
+ * Jan 06, 2014 2707 bclement changed unique constraint from officeId to stationId
*
*
*
@@ -81,7 +82,7 @@ import com.vividsolutions.jts.geom.Geometry;
@Entity
@SequenceGenerator(initialValue = 1, name = PluginDataObject.ID_GEN, sequenceName = "lsrseq")
@Table(name = "lsr", uniqueConstraints = { @UniqueConstraint(columnNames = {
- "latitude", "longitude", "officeId", "refTime", "forecastTime",
+ "latitude", "longitude", "stationId", "refTime", "forecastTime",
"eventType" }) })
/*
* Both refTime and forecastTime are included in the refTimeIndex since
diff --git a/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/config/FSSObsMonitorConfigurationManager.java b/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/config/FSSObsMonitorConfigurationManager.java
index bf097dab20..303d137e0d 100644
--- a/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/config/FSSObsMonitorConfigurationManager.java
+++ b/edexOsgi/com.raytheon.uf.common.monitor/src/com/raytheon/uf/common/monitor/config/FSSObsMonitorConfigurationManager.java
@@ -528,11 +528,11 @@ public class FSSObsMonitorConfigurationManager implements
}
/**
- * Gets an area of a station.
+ * Gets the zones where station is monitoring
*
* @param stationId
- * The station to get the area
- * @return List of areas
+ * The station to get the zones
+ * @return List of zones
*/
public List getAreaByStationId(String stationId) {
List results = new ArrayList();
diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.fog/src/com/raytheon/uf/edex/plugin/fog/common/FogConfig.java b/edexOsgi/com.raytheon.uf.edex.plugin.fog/src/com/raytheon/uf/edex/plugin/fog/common/FogConfig.java
index d94718077d..95493dcd88 100644
--- a/edexOsgi/com.raytheon.uf.edex.plugin.fog/src/com/raytheon/uf/edex/plugin/fog/common/FogConfig.java
+++ b/edexOsgi/com.raytheon.uf.edex.plugin.fog/src/com/raytheon/uf/edex/plugin/fog/common/FogConfig.java
@@ -132,7 +132,6 @@ public class FogConfig {
// our new coverage boundaries including adjacent areas
Geometry monitorAreaGeo = AdjacentWfoMgr.getAdjacentAreas(getCwa());
// (SK) Geometry monitorAreaGeo =
- // FogDbUtils.getMonitoringAreaGeometry(filter.getCwaGeometry(),getCwa());
setCenter(monitorAreaGeo.getCentroid().getCoordinate());
Coordinate[] coords = monitorAreaGeo.getEnvelope().getCoordinates();
this.upperLeftCorner = coords[1];
diff --git a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/CredentialCache.java b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/CredentialCache.java
index 66db1cdad9..5746bf4778 100644
--- a/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/CredentialCache.java
+++ b/edexOsgi/com.raytheon.uf.edex.registry.ebxml/src/com/raytheon/uf/edex/registry/ebxml/web/security/CredentialCache.java
@@ -42,6 +42,10 @@ import com.raytheon.uf.common.registry.constants.RegistryObjectTypes;
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
import com.raytheon.uf.common.registry.services.RegistryServiceException;
import com.raytheon.uf.common.security.encryption.AESEncryptor;
+import com.raytheon.uf.common.status.IUFStatusHandler;
+import com.raytheon.uf.common.status.UFStatus;
+import com.raytheon.uf.common.status.UFStatus.Priority;
+import com.raytheon.uf.common.util.ClusterIdUtil;
import com.raytheon.uf.edex.registry.ebxml.RegistryUsers;
import com.raytheon.uf.edex.registry.ebxml.dao.PersonDao;
import com.raytheon.uf.edex.registry.ebxml.services.RegistryRESTServices;
@@ -61,6 +65,7 @@ import com.raytheon.uf.edex.security.SecurityConfiguration;
* ------------ ---------- ----------- --------------------------
* 7/10/2014 1717 bphillip Initial creation
* 7/24/2014 1712 bphillip No longer singleton
+ * 1/06/2015 3918 dhladky Fixed issue where clients can't start without central registry.
*
*
* @author bphillip
@@ -87,10 +92,26 @@ public class CredentialCache {
public static final boolean centralRegistry = System.getProperty(
"edex.run.mode").equals("centralRegistry");
+ /** States whether this node will join the federation */
+ public static final boolean isFederationEnabled = Boolean
+ .getBoolean("ebxml.registry.federation.enabled");
+
/** Address of the central registry */
private static final String CENTRAL_REGISTRY_ADDRESS = "https://"
+ (System.getProperty("ncf.host")) + ":"
+ (System.getProperty("ebxml.registry.webserver.port"));
+
+ private static final IUFStatusHandler statusHandler = UFStatus
+ .getHandler(CredentialCache.class);
+
+ /** used in non federated standalone environment */
+ private static final String DEFAULT_USER = "DEFAULT_USER_"+ClusterIdUtil.getId();
+
+ /** used in non federated standalone environment */
+ private static final String DEFAULT_PASSWORD = "DEFAULT_PASSWORD_"+ClusterIdUtil.getId();
+
+ /** used in non federated standalone environment */
+ private static final String DEFAULT_ROLE = "DEFAULT_ROLE_"+ClusterIdUtil.getId();
/** Cache holding users' credentials */
private LoadingCache credentialCache = CacheBuilder
@@ -115,12 +136,16 @@ public class CredentialCache {
user = personDao.getById(userName
+ RegistryUsers.USER_SUFFIX);
}
- /*
- * If we are not the central registry, query
- * the central registry to get the user's
- * information
- */
- else {
+
+ // This is a case required if you are
+ // connected to a central registry.
+ if (isFederationEnabled) {
+
+ /*
+ * If we are not the central registry,
+ * query the central registry to get the
+ * user's information
+ */
try {
user = restServices
.getRegistryObject(
@@ -132,36 +157,58 @@ public class CredentialCache {
"Error contacting central registry!",
e);
}
+
+ /*
+ * User not found means unauthorized
+ */
+ if (user == null) {
+ throw new WebServiceException(
+ "User ["
+ + userName
+ + " Not authorized!");
+
+ } else {
+ /*
+ * Put the user name, password, and
+ * role in the return array. Decrypt
+ * the password.
+ */
+ String userName = user
+ .getSlotValue(RegistryUsers.USER_SLOT_NAME);
+ String password = null;
+ try {
+ password = encryption.decrypt(
+ securityConfig
+ .getEncryptionKey(),
+ (String) user
+ .getSlotValue(RegistryUsers.PASSWORD_SLOT_NAME));
+ } catch (Exception e) {
+ throw new RegistryServiceException(
+ "Error decrypting password!",
+ e);
+ }
+ String role = user
+ .getSlotValue(RegistryUsers.ROLE_SLOT_NAME);
+ return new String[] { userName,
+ password, role };
+ }
}
+
/*
- * User not found means unauthorized
+ * This is a case where you are not
+ * connected to a central registry
+ * (Standalone server and edge condition),
+ * use defaults.
*/
- if (user == null) {
- throw new WebServiceException("User ["
- + userName + " Not authorized!");
+ else {
+ statusHandler
+ .handle(Priority.INFO,
+ "Federation not enabled! Proceeding with default user, pass, and role!");
+ return new String[] { DEFAULT_USER,
+ DEFAULT_PASSWORD, DEFAULT_ROLE };
}
- /*
- * Put the user name, password, and role in
- * the return array. Decrypt the password.
- */
- String userName = user
- .getSlotValue(RegistryUsers.USER_SLOT_NAME);
- String password = null;
- try {
- password = encryption.decrypt(
- securityConfig
- .getEncryptionKey(),
- (String) user
- .getSlotValue(RegistryUsers.PASSWORD_SLOT_NAME));
- } catch (Exception e) {
- throw new RegistryServiceException(
- "Error decrypting password!", e);
- }
- String role = user
- .getSlotValue(RegistryUsers.ROLE_SLOT_NAME);
- return new String[] { userName, password,
- role };
}
+
});
}
});
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips.patch b/rpms/awips2.qpid/0.18/SOURCES/awips.patch
deleted file mode 100644
index a678d65890..0000000000
--- a/rpms/awips2.qpid/0.18/SOURCES/awips.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-diff -crB a/qpid/java/broker/bin/qpid-passwd b/qpid/java/broker/bin/qpid-passwd
-*** a/qpid/java/broker/bin/qpid-passwd 2012-02-15 09:29:22.000000000 -0600
---- b/qpid/java/broker/bin/qpid-passwd 2013-07-30 16:23:13.000000000 -0500
-***************
-*** 24,30 ****
- fi
-
- # Set classpath to include Qpid jar with all required jars in manifest
-! QPID_LIBS=$QPID_HOME/lib/qpid-all.jar
-
- # Set other variables used by the qpid-run script before calling
- export JAVA=java \
---- 24,30 ----
- fi
-
- # Set classpath to include Qpid jar with all required jars in manifest
-! QPID_LIBS="$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/opt/*:$QPID_HOME/lib/opt/qpid-deps/*"
-
- # Set other variables used by the qpid-run script before calling
- export JAVA=java \
-diff -crB a/qpid/java/broker/bin/qpid-server b/qpid/java/broker/bin/qpid-server
-*** a/qpid/java/broker/bin/qpid-server 2011-09-30 08:38:14.000000000 -0500
---- b/qpid/java/broker/bin/qpid-server 2013-07-30 16:23:13.000000000 -0500
-***************
-*** 23,30 ****
- fi
-
- if [ -z "$QPID_WORK" ]; then
-! echo "Setting QPID_WORK to $HOME as default"
-! QPID_WORK=$HOME
- fi
-
- # Set to help us get round the manifold problems of ps/pgrep on various
---- 23,29 ----
- fi
-
- if [ -z "$QPID_WORK" ]; then
-! export QPID_WORK=$QPID_HOME
- fi
-
- # Set to help us get round the manifold problems of ps/pgrep on various
-***************
-*** 34,43 ****
- fi
-
- # Set classpath to include the qpid-all manifest jar, and any jars supplied in lib/opt
-! QPID_LIBS="$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/opt/*"
-
- # Set other variables used by the qpid-run script before calling
-! export JAVA=java \
- JAVA_VM=-server \
- JAVA_MEM=-Xmx1024m \
- JAVA_GC="-XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError" \
---- 33,42 ----
- fi
-
- # Set classpath to include the qpid-all manifest jar, and any jars supplied in lib/opt
-! QPID_LIBS="$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/opt/*:$QPID_HOME/lib/opt/qpid-deps/*"
-
- # Set other variables used by the qpid-run script before calling
-! export JAVA=/awips2/java/bin/java \
- JAVA_VM=-server \
- JAVA_MEM=-Xmx1024m \
- JAVA_GC="-XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError" \
-Only in b/qpid/java/broker/bin: qpid-server.orig
-diff -crB a/qpid/java/build.deps b/qpid/java/build.deps
-*** a/qpid/java/build.deps 2012-07-08 10:28:32.000000000 -0500
---- b/qpid/java/build.deps 2013-07-30 16:23:13.000000000 -0500
-***************
-*** 17,29 ****
- # under the License.
- #
-
-! commons-beanutils-core=lib/required/commons-beanutils-core-1.8.3.jar
- commons-cli=lib/required/commons-cli-1.2.jar
-! commons-codec=lib/required/commons-codec-1.6.jar
- commons-collections=lib/required/commons-collections-3.2.1.jar
- commons-configuration=lib/required/commons-configuration-1.8.jar
- commons-digester=lib/required/commons-digester-1.8.1.jar
-! commons-lang=lib/required/commons-lang-2.6.jar
- commons-logging=lib/required/commons-logging-1.1.1.jar
-
- derby-db=lib/required/derby-10.8.2.2.jar
---- 17,29 ----
- # under the License.
- #
-
-! commons-beanutils-core=lib/required/commons-beanutils-1.8.3.jar
- commons-cli=lib/required/commons-cli-1.2.jar
-! commons-codec=lib/required/commons-codec-1.4.jar
- commons-collections=lib/required/commons-collections-3.2.1.jar
- commons-configuration=lib/required/commons-configuration-1.8.jar
- commons-digester=lib/required/commons-digester-1.8.1.jar
-! commons-lang=lib/required/commons-lang-2.3.jar
- commons-logging=lib/required/commons-logging-1.1.1.jar
-
- derby-db=lib/required/derby-10.8.2.2.jar
-***************
-*** 33,39 ****
- geronimo-jta=lib/required/geronimo-jta_1.1_spec-1.1.1.jar
- geronimo-kernel=lib/required/geronimo-kernel-2.2.1.jar
- geronimo-openejb=lib/required/geronimo-ejb_3.0_spec-1.0.1.jar
-! geronimo-servlet=lib/required/geronimo-servlet_2.5_spec-1.2.jar
-
- junit=lib/required/junit-3.8.1.jar
- mockito-all=lib/required/mockito-all-1.9.0.jar
---- 33,39 ----
- geronimo-jta=lib/required/geronimo-jta_1.1_spec-1.1.1.jar
- geronimo-kernel=lib/required/geronimo-kernel-2.2.1.jar
- geronimo-openejb=lib/required/geronimo-ejb_3.0_spec-1.0.1.jar
-! geronimo-servlet=lib/required/geronimo-servlet_2.5_spec-1.1.2.jar
-
- junit=lib/required/junit-3.8.1.jar
- mockito-all=lib/required/mockito-all-1.9.0.jar
-***************
-*** 45,51 ****
- slf4j-api=lib/required/slf4j-api-1.6.4.jar
- slf4j-log4j=lib/required/slf4j-log4j12-1.6.4.jar
-
-! xalan=lib/required/xalan-2.7.0.jar
-
- jetty=lib/required/jetty-server-7.6.3.v20120416.jar
- jetty-continuation=lib/required/jetty-continuation-7.6.3.v20120416.jar
---- 45,51 ----
- slf4j-api=lib/required/slf4j-api-1.6.4.jar
- slf4j-log4j=lib/required/slf4j-log4j12-1.6.4.jar
-
-! xalan=lib/required/xalan-2.7.1.jar
-
- jetty=lib/required/jetty-server-7.6.3.v20120416.jar
- jetty-continuation=lib/required/jetty-continuation-7.6.3.v20120416.jar
-***************
-*** 63,70 ****
-
- felix.libs=${felix-main}
-
-! jackson-core=lib/required/jackson-core-asl-1.9.0.jar
-! jackson-mapper=lib/required/jackson-mapper-asl-1.9.0.jar
-
- commons-configuration.libs = ${commons-beanutils-core} ${commons-digester} \
- ${commons-codec} ${commons-lang} ${commons-collections} ${commons-configuration}
---- 63,70 ----
-
- felix.libs=${felix-main}
-
-! jackson-core=lib/required/jackson-core-asl-1.7.3.jar
-! jackson-mapper=lib/required/jackson-mapper-asl-1.7.3.jar
-
- commons-configuration.libs = ${commons-beanutils-core} ${commons-digester} \
- ${commons-codec} ${commons-lang} ${commons-collections} ${commons-configuration}
-Only in b/qpid/java: build.deps.orig
-diff -crB a/qpid/java/common/bin/qpid-jaddr b/qpid/java/common/bin/qpid-jaddr
-*** a/qpid/java/common/bin/qpid-jaddr 2010-06-07 15:13:47.000000000 -0500
---- b/qpid/java/common/bin/qpid-jaddr 2013-07-30 16:23:13.000000000 -0500
-***************
-*** 24,30 ****
- fi
-
- # Set classpath to include Qpid jar with all required jars in manifest
-! QPID_LIBS=$QPID_HOME/lib/qpid-all.jar
-
- # Set other variables used by the qpid-run script before calling
- export JAVA=java \
---- 24,30 ----
- fi
-
- # Set classpath to include Qpid jar with all required jars in manifest
-! QPID_LIBS="$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/opt/*:$QPID_HOME/lib/opt/qpid-deps/*"
-
- # Set other variables used by the qpid-run script before calling
- export JAVA=java \
-diff -crB a/qpid/java/common/bin/qpid-run b/qpid/java/common/bin/qpid-run
-*** a/qpid/java/common/bin/qpid-run 2012-02-15 09:29:22.000000000 -0600
---- b/qpid/java/common/bin/qpid-run 2013-07-30 16:23:13.000000000 -0500
-***************
-*** 62,69 ****
- fi
-
- if [ -z "$QPID_WORK" ]; then
-! log $INFO Setting QPID_WORK to $HOME as default
-! QPID_WORK=$HOME
- fi
-
- if [ -z "$JAVA" ]; then
---- 62,68 ----
- fi
-
- if [ -z "$QPID_WORK" ]; then
-! QPID_WORK=$QPID_HOME
- fi
-
- if [ -z "$JAVA" ]; then
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/commons-configuration-1.8.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/commons-configuration-1.8.jar
deleted file mode 100644
index ae9ae9969b..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/commons-configuration-1.8.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/commons-logging-1.1.2.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/commons-logging-1.1.2.jar
deleted file mode 100644
index d6a543c4ed..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/commons-logging-1.1.2.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/dependencies.txt b/rpms/awips2.qpid/0.18/SOURCES/awips2/dependencies.txt
deleted file mode 100644
index 0164c36768..0000000000
--- a/rpms/awips2.qpid/0.18/SOURCES/awips2/dependencies.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-org.apache.commons.cli/commons-cli-1.2.jar
-org.apache.xalan/xalan-2.7.2.jar
-org.apache.commons.beanutils/commons-beanutils-1.8.3.jar
-org.apache.commons.digester/commons-digester-1.8.1.jar
-org.apache.commons.codec/commons-codec-1.4.jar
-org.apache.commons.lang/commons-lang-2.3.jar
-org.apache.commons.collections/commons-collections-3.2.jar
-org.codehaus.jackson/jackson-core-asl-1.7.3.jar
-org.codehaus.jackson/jackson-mapper-asl-1.7.3.jar
-org.mockito/mockito-all-1.9.0.jar
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/derby.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/derby.jar
deleted file mode 100644
index b59555907a..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/derby.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/dojo-war-1.7.2.war b/rpms/awips2.qpid/0.18/SOURCES/awips2/dojo-war-1.7.2.war
deleted file mode 100644
index e42e2a4b9f..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/dojo-war-1.7.2.war and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/geronimo-servlet_2.5_spec-1.1.2.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/geronimo-servlet_2.5_spec-1.1.2.jar
deleted file mode 100644
index 94733327f2..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/geronimo-servlet_2.5_spec-1.1.2.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-continuation-7.6.3.v20120416.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-continuation-7.6.3.v20120416.jar
deleted file mode 100644
index 0aa38b8fb9..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-continuation-7.6.3.v20120416.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-http-7.6.3.v20120416.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-http-7.6.3.v20120416.jar
deleted file mode 100644
index 297f2e0953..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-http-7.6.3.v20120416.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-io-7.6.3.v20120416.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-io-7.6.3.v20120416.jar
deleted file mode 100644
index a0496268b8..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-io-7.6.3.v20120416.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-security-7.6.3.v20120416.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-security-7.6.3.v20120416.jar
deleted file mode 100644
index 9f428298e2..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-security-7.6.3.v20120416.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-server-7.6.3.v20120416.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-server-7.6.3.v20120416.jar
deleted file mode 100644
index 7dcfd1cd85..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-server-7.6.3.v20120416.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-servlet-7.6.3.v20120416.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-servlet-7.6.3.v20120416.jar
deleted file mode 100644
index fc0bc16c1a..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-servlet-7.6.3.v20120416.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-util-7.6.3.v20120416.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-util-7.6.3.v20120416.jar
deleted file mode 100644
index e3ba8cf14c..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-util-7.6.3.v20120416.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-websocket-7.6.3.v20120416.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-websocket-7.6.3.v20120416.jar
deleted file mode 100644
index 1912e971cb..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/jetty-websocket-7.6.3.v20120416.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/org.apache.felix.main-2.0.5.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/org.apache.felix.main-2.0.5.jar
deleted file mode 100644
index 71e5a84231..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/org.apache.felix.main-2.0.5.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/awips2/slf4j-log4j12-1.7.5.jar b/rpms/awips2.qpid/0.18/SOURCES/awips2/slf4j-log4j12-1.7.5.jar
deleted file mode 100644
index afce5c21f1..0000000000
Binary files a/rpms/awips2.qpid/0.18/SOURCES/awips2/slf4j-log4j12-1.7.5.jar and /dev/null differ
diff --git a/rpms/awips2.qpid/0.18/SOURCES/build.patch b/rpms/awips2.qpid/0.18/SOURCES/build.patch
deleted file mode 100644
index 0e1cd77bd0..0000000000
--- a/rpms/awips2.qpid/0.18/SOURCES/build.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/qpid/java/build.xml b/qpid/java/build.xml
-index a41cff4..06e8c8a 100644
---- a/qpid/java/build.xml
-+++ b/qpid/java/build.xml
-@@ -161,7 +161,7 @@
-
-
-
--
-+
-
-
-
diff --git a/rpms/awips2.qpid/0.18/SOURCES/config.xml b/rpms/awips2.qpid/0.18/SOURCES/config.xml
deleted file mode 100644
index 6f18bba4ff..0000000000
--- a/rpms/awips2.qpid/0.18/SOURCES/config.xml
+++ /dev/null
@@ -1,121 +0,0 @@
-
-
-
-
- ${QPID_HOME}
- ${QPID_WORK}
- ${prefix}/etc
-
- ${QPID_HOME}/lib/opt
- ${QPID_WORK}/cache
-
-
-
-
- false
- 5671
- false
- /path/to/keystore.ks
- keystorepass
-
- 5672
- 32768
- 16384
-
-
- true
-
- 8999
-
-
-
- false
-
- ${conf}/qpid.keystore
- password
-
-
- true
- 8180
- false
- false
- 600
-
-
- false
-
-
-
- 65535
- en_US
-
-
-
-
-
- org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase
-
-
- passwordFile
- ${conf}/passwd
-
-
-
-
-
-
-
-
-
- false
-
-
- ${conf}/virtualhosts.xml
-
-
- 0
- 2.0
-
-
- true
-
-
- ON
-
-
diff --git a/rpms/awips2.qpid/0.18/SOURCES/examples.patch b/rpms/awips2.qpid/0.18/SOURCES/examples.patch
deleted file mode 100644
index 518cb93df5..0000000000
--- a/rpms/awips2.qpid/0.18/SOURCES/examples.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 4acdbf975c076c2c49e7e2436065ca7d18dfab20 Mon Sep 17 00:00:00 2001
-From: rajith
-Date: Wed, 16 Jun 2010 16:37:11 -0400
-Subject: [PATCH 02/52] These two files are not present in upstream and we currently carry them as a patch.
- The reason being that the run_example.sh is tailored specific for the linux env.
- Including the example.log4j depends on how the release artefacts will look like for the 0.7 qpid release.
-
----
- qpid/java/client/example/bin/run_example.sh | 43 +++++++++++++++++++++++++++
- qpid/java/client/example/example.log4j | 27 +++++++++++++++++
- 2 files changed, 70 insertions(+), 0 deletions(-)
- create mode 100644 qpid/java/client/example/bin/run_example.sh
- create mode 100644 qpid/java/client/example/example.log4j
-
-diff --git a/qpid/java/client/example/bin/run_example.sh b/qpid/java/client/example/bin/run_example.sh
-new file mode 100644
-index 0000000..5bd0e99
---- /dev/null
-+++ b/qpid/java/client/example/bin/run_example.sh
-@@ -0,0 +1,43 @@
-+#!/bin/bash
-+
-+#
-+# 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.
-+#
-+
-+# set the CLASSPATH
-+QPID_DEPS=`find /usr/share/java/qpid-deps/*.jar | tr '\n' ":"`
-+QPID_JARS=`find /usr/share/java -name 'qpid-client*.jar' -or -name 'qpid-common*.jar' | tr '\n' ":"`
-+LOG4J="/usr/share/java/log4j.jar"
-+QPID_CLASSPATH=$QPID_DEPS$LOG4J:$QPID_JARS
-+
-+# compile the samples
-+javac -cp "$QPID_CLASSPATH" -sourcepath "$PWD" -d . `find $PWD -name '*.java'`
-+
-+# Add output classes to CLASSPATH
-+QPID_CLASSPATH="$PWD:$QPID_CLASSPATH"
-+
-+
-+# Check if the user supplied a sample classname
-+if test "'x$1'" = "'x'"
-+then
-+ echo "No sample classname specified"
-+ exit;
-+else
-+ java -cp $QPID_CLASSPATH -Dlog4j.configuration=example.log4j "$@"
-+fi
-+
-diff --git a/qpid/java/client/example/example.log4j b/qpid/java/client/example/example.log4j
-new file mode 100644
-index 0000000..50b4ed2
---- /dev/null
-+++ b/qpid/java/client/example/example.log4j
-@@ -0,0 +1,27 @@
-+#
-+# 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.
-+#
-+
-+log4j.logger.org.apache.qpid=WARN, console
-+log4j.additivity.org.apache.qpid=false
-+
-+
-+log4j.appender.console=org.apache.log4j.ConsoleAppender
-+log4j.appender.console.Threshold=all
-+log4j.appender.console.layout=org.apache.log4j.PatternLayout
-+log4j.appender.console.layout.ConversionPattern=%t %d %p [%c{4}] %m%n
diff --git a/rpms/awips2.qpid/0.18/SOURCES/log4j.xml b/rpms/awips2.qpid/0.18/SOURCES/log4j.xml
deleted file mode 100644
index 4ada971857..0000000000
--- a/rpms/awips2.qpid/0.18/SOURCES/log4j.xml
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/rpms/awips2.qpid/0.18/SOURCES/mrg.patch b/rpms/awips2.qpid/0.18/SOURCES/mrg.patch
deleted file mode 100644
index 5bc1665d34..0000000000
--- a/rpms/awips2.qpid/0.18/SOURCES/mrg.patch
+++ /dev/null
@@ -1,4090 +0,0 @@
-From 862f9df4e6e14995b80f8162601959a61ca765d4 Mon Sep 17 00:00:00 2001
-From: Kenneth Giusti
-Date: Wed, 5 Sep 2012 13:25:51 -0400
-Subject: [PATCH 01/19] BZ854004: perform header lookup while the message is locked.
-
----
- qpid/cpp/src/qpid/broker/Message.cpp | 9 +++++++++
- qpid/cpp/src/qpid/broker/Message.h | 1 +
- qpid/cpp/src/qpid/broker/MessageGroupManager.cpp | 13 +++++--------
- 3 files changed, 15 insertions(+), 8 deletions(-)
-
-diff --git a/qpid/cpp/src/qpid/broker/Message.cpp b/qpid/cpp/src/qpid/broker/Message.cpp
-index 4dd8a34..1a91504 100644
---- a/qpid/cpp/src/qpid/broker/Message.cpp
-+++ b/qpid/cpp/src/qpid/broker/Message.cpp
-@@ -100,6 +100,15 @@ const FieldTable* Message::getApplicationHeaders() const
- return getAdapter().getApplicationHeaders(frames);
- }
-
-+const FieldTable::ValuePtr Message::getApplicationHeader(const std::string& name) const
-+{
-+ sys::Mutex::ScopedLock l(lock);
-+
-+ const FieldTable *ft = getAdapter().getApplicationHeaders(frames);
-+ if (!ft) return FieldTable::ValuePtr();
-+ return ft->get( name );
-+}
-+
- std::string Message::getAppId() const
- {
- sys::Mutex::ScopedLock l(lock);
-diff --git a/qpid/cpp/src/qpid/broker/Message.h b/qpid/cpp/src/qpid/broker/Message.h
-index 90e4eec..f002001 100644
---- a/qpid/cpp/src/qpid/broker/Message.h
-+++ b/qpid/cpp/src/qpid/broker/Message.h
-@@ -77,6 +77,7 @@ public:
- QPID_BROKER_EXTERN std::string getExchangeName() const;
- bool isImmediate() const;
- QPID_BROKER_EXTERN const framing::FieldTable* getApplicationHeaders() const;
-+ QPID_BROKER_EXTERN const framing::FieldTable::ValuePtr getApplicationHeader(const std::string&) const;
- QPID_BROKER_EXTERN std::string getAppId() const;
- QPID_BROKER_EXTERN bool isPersistent() const;
- bool requiresAccept();
-diff --git a/qpid/cpp/src/qpid/broker/MessageGroupManager.cpp b/qpid/cpp/src/qpid/broker/MessageGroupManager.cpp
-index 15cd56a..bc5d797 100644
---- a/qpid/cpp/src/qpid/broker/MessageGroupManager.cpp
-+++ b/qpid/cpp/src/qpid/broker/MessageGroupManager.cpp
-@@ -84,14 +84,11 @@ MessageGroupManager::GroupState& MessageGroupManager::findGroup( const QueuedMes
- }
-
- std::string group = defaultGroupId;
-- const qpid::framing::FieldTable* headers = qm.payload->getApplicationHeaders();
-- if (headers) {
-- qpid::framing::FieldTable::ValuePtr id = headers->get( groupIdHeader );
-- if (id && id->convertsTo()) {
-- std::string tmp = id->get();
-- if (!tmp.empty()) // empty group is reserved
-- group = tmp;
-- }
-+ const qpid::framing::FieldTable::ValuePtr id = qm.payload->getApplicationHeader(groupIdHeader);
-+ if (id && id->convertsTo()) {
-+ std::string tmp = id->get();
-+ if (!tmp.empty()) // empty group is reserved
-+ group = tmp;
- }
-
- if (cachedGroup && group == lastGroup) {
---
-1.7.1
-
-From ccf535a5a75e413557385adcc6874d8a47af1c17 Mon Sep 17 00:00:00 2001
-From: Kenneth Giusti
-Date: Thu, 6 Sep 2012 10:03:44 -0400
-Subject: [PATCH 02/19] BZ854004 - remove risky use of broker::Message::getApplicationHeaders()
-
----
- qpid/cpp/src/qpid/broker/Link.cpp | 5 +++--
- qpid/cpp/src/qpid/broker/Message.cpp | 11 ++++++++---
- qpid/cpp/src/qpid/broker/Message.h | 4 ++++
- qpid/cpp/src/qpid/broker/MessageMap.cpp | 5 +++--
- qpid/cpp/src/qpid/broker/Queue.cpp | 4 +---
- qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp | 5 +++--
- qpid/cpp/src/qpid/cluster/CredentialsExchange.cpp | 7 ++++---
- 7 files changed, 26 insertions(+), 15 deletions(-)
-
-diff --git a/qpid/cpp/src/qpid/broker/Link.cpp b/qpid/cpp/src/qpid/broker/Link.cpp
-index 84dd163..a853240 100644
---- a/qpid/cpp/src/qpid/broker/Link.cpp
-+++ b/qpid/cpp/src/qpid/broker/Link.cpp
-@@ -33,6 +33,7 @@
- #include "qpid/broker/AclModule.h"
- #include "qpid/broker/Exchange.h"
- #include "qpid/UrlArray.h"
-+#include "qpid/framing/FieldValue.h"
-
- namespace qpid {
- namespace broker {
-@@ -95,9 +96,9 @@ public:
- void route(broker::Deliverable& msg)
- {
- if (!link) return;
-- const framing::FieldTable* headers = msg.getMessage().getApplicationHeaders();
-+ const framing::FieldTable::ValuePtr header = msg.getMessage().getApplicationHeader(FAILOVER_HEADER_KEY);
- framing::Array addresses;
-- if (headers && headers->getArray(FAILOVER_HEADER_KEY, addresses)) {
-+ if (header && framing::getEncodedValue(header, addresses)) {
- // convert the Array of addresses to a single Url container for used with setUrl():
- std::vector urlVec;
- Url urls;
-diff --git a/qpid/cpp/src/qpid/broker/Message.cpp b/qpid/cpp/src/qpid/broker/Message.cpp
-index 1a91504..d8719c7 100644
---- a/qpid/cpp/src/qpid/broker/Message.cpp
-+++ b/qpid/cpp/src/qpid/broker/Message.cpp
-@@ -94,17 +94,22 @@ bool Message::isImmediate() const
- return getAdapter().isImmediate(frames);
- }
-
-+const FieldTable* Message::getApplicationHeadersLH() const
-+{
-+ return getAdapter().getApplicationHeaders(frames);
-+}
-+
- const FieldTable* Message::getApplicationHeaders() const
- {
- sys::Mutex::ScopedLock l(lock);
-- return getAdapter().getApplicationHeaders(frames);
-+ return getApplicationHeadersLH();
- }
-
- const FieldTable::ValuePtr Message::getApplicationHeader(const std::string& name) const
- {
- sys::Mutex::ScopedLock l(lock);
-
-- const FieldTable *ft = getAdapter().getApplicationHeaders(frames);
-+ const FieldTable *ft = getApplicationHeadersLH();
- if (!ft) return FieldTable::ValuePtr();
- return ft->get( name );
- }
-@@ -339,7 +344,7 @@ const std::string X_QPID_TRACE("x-qpid.trace");
- bool Message::isExcluded(const std::vector& excludes) const
- {
- sys::Mutex::ScopedLock l(lock);
-- const FieldTable* headers = getApplicationHeaders();
-+ const FieldTable* headers = getApplicationHeadersLH();
- if (headers) {
- std::string traceStr = headers->getAsString(X_QPID_TRACE);
- if (traceStr.size()) {
-diff --git a/qpid/cpp/src/qpid/broker/Message.h b/qpid/cpp/src/qpid/broker/Message.h
-index f002001..7af2f00 100644
---- a/qpid/cpp/src/qpid/broker/Message.h
-+++ b/qpid/cpp/src/qpid/broker/Message.h
-@@ -76,6 +76,9 @@ public:
- const boost::shared_ptr getExchange(ExchangeRegistry&) const;
- QPID_BROKER_EXTERN std::string getExchangeName() const;
- bool isImmediate() const;
-+ // Note: getApplicationHeaders() cannot be used when the message is shared between queues (or threads).
-+ // The returned FieldTable will be deallocated should another thread rewrite the message headers!
-+ // See BZ854004. When in doubt, don't use this method - use getApplicationHeader() instead.
- QPID_BROKER_EXTERN const framing::FieldTable* getApplicationHeaders() const;
- QPID_BROKER_EXTERN const framing::FieldTable::ValuePtr getApplicationHeader(const std::string&) const;
- QPID_BROKER_EXTERN std::string getAppId() const;
-@@ -210,6 +213,7 @@ public:
- return getHeaderBody()->get(true);
- }
- qpid::framing::AMQHeaderBody* getHeaderBody();
-+ const qpid::framing::FieldTable* getApplicationHeadersLH() const;
- };
-
- }}
-diff --git a/qpid/cpp/src/qpid/broker/MessageMap.cpp b/qpid/cpp/src/qpid/broker/MessageMap.cpp
-index 592f3fe..de0137e 100644
---- a/qpid/cpp/src/qpid/broker/MessageMap.cpp
-+++ b/qpid/cpp/src/qpid/broker/MessageMap.cpp
-@@ -21,6 +21,7 @@
- #include "qpid/broker/MessageMap.h"
- #include "qpid/broker/QueuedMessage.h"
- #include "qpid/log/Statement.h"
-+#include "qpid/framing/FieldValue.h"
- #include
-
- namespace qpid {
-@@ -42,8 +43,8 @@ bool MessageMap::deleted(const QueuedMessage& message)
-
- std::string MessageMap::getKey(const QueuedMessage& message)
- {
-- const framing::FieldTable* ft = message.payload->getApplicationHeaders();
-- if (ft) return ft->getAsString(key);
-+ const framing::FieldTable::ValuePtr val = message.payload->getApplicationHeader(key);
-+ if (val && val->convertsTo()) return val->get();
- else return EMPTY;
- }
-
-diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp
-index 3202a26..561ac99 100644
---- a/qpid/cpp/src/qpid/broker/Queue.cpp
-+++ b/qpid/cpp/src/qpid/broker/Queue.cpp
-@@ -688,9 +688,7 @@ namespace {
- : MessageFilter (), header(_header), value(_value) {}
- bool match( const QueuedMessage& msg ) const
- {
-- const qpid::framing::FieldTable* headers = msg.payload->getApplicationHeaders();
-- if (!headers) return false;
-- FieldTable::ValuePtr h = headers->get(header);
-+ const FieldTable::ValuePtr h = msg.payload->getApplicationHeader(header);
- if (!h || !h->convertsTo()) return false;
- return h->get() == value;
- }
-diff --git a/qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp b/qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp
-index 3c9e210..c0fe733 100644
---- a/qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp
-+++ b/qpid/cpp/src/qpid/broker/ThresholdAlerts.cpp
-@@ -25,6 +25,7 @@
- #include "qpid/log/Statement.h"
- #include "qpid/management/ManagementAgent.h"
- #include "qmf/org/apache/qpid/broker/EventQueueThresholdExceeded.h"
-+#include "qpid/framing/FieldValue.h"
-
- namespace qpid {
- namespace broker {
-@@ -41,8 +42,8 @@ bool isThresholdEvent(const boost::intrusive_ptr message)
- if (message->getIsManagementMessage()) {
- //is this a qmf event? if so is it a threshold event?
- if (isQMFv2(message)) {
-- const qpid::framing::FieldTable* headers = message->getApplicationHeaders();
-- if (headers && headers->getAsString("qmf.content") == "_event") {
-+ const qpid::framing::FieldTable::ValuePtr header = message->getApplicationHeader("qmf.content");
-+ if (header && header->convertsTo() && header->get() == std::string("_event")) {
- //decode as list
- std::string content = message->getFrames().getContent();
- qpid::types::Variant::List list;
-diff --git a/qpid/cpp/src/qpid/cluster/CredentialsExchange.cpp b/qpid/cpp/src/qpid/cluster/CredentialsExchange.cpp
-index 416a363..93488a6 100644
---- a/qpid/cpp/src/qpid/cluster/CredentialsExchange.cpp
-+++ b/qpid/cpp/src/qpid/cluster/CredentialsExchange.cpp
-@@ -23,6 +23,7 @@
- #include "qpid/broker/ConnectionState.h"
- #include "qpid/framing/reply_exceptions.h"
- #include "qpid/sys/Time.h"
-+#include "qpid/framing/FieldValue.h"
-
- namespace qpid {
- namespace cluster {
-@@ -63,7 +64,7 @@ bool CredentialsExchange::check(MemberId member) {
- }
-
- void CredentialsExchange::route(broker::Deliverable& msg) {
-- const framing::FieldTable* args = msg.getMessage().getApplicationHeaders();
-+ const framing::FieldTable::ValuePtr name = msg.getMessage().getApplicationHeader(NAME);
- sys::Mutex::ScopedLock l(lock);
- const broker::ConnectionState* connection =
- static_cast(msg.getMessage().getPublisher());
-@@ -71,10 +72,10 @@ void CredentialsExchange::route(broker::Deliverable& msg) {
- throw framing::UnauthorizedAccessException(
- QPID_MSG("Unauthorized user " << connection->getUserId() << " for " << NAME
- << ", should be " << username));
-- if (!args || !args->isSet(NAME))
-+ if (!name)
- throw framing::InvalidArgumentException(
- QPID_MSG("Invalid message received by " << NAME));
-- MemberId member(args->getAsUInt64(NAME));
-+ MemberId member(name->getIntegerValue());
- map[member] = sys::AbsTime::now();
- }
-
---
-1.7.1
-
-From e4b8f2996de58d5d80a969c804973254bbf569a8 Mon Sep 17 00:00:00 2001
-From: Rajith Muditha Attapattu
-Date: Fri, 31 Aug 2012 15:30:55 +0000
-Subject: [PATCH 03/19] Bug 852030, QPID-4267: Prevent multiple inclusion of ra.xml and jboss-ra.xml files in JCA jar and JCA rar
-
-git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1379478 13f79535-47bb-0310-9956-ffa450edef68
----
- qpid/java/jca/build.xml | 13 +++++++++++--
- 1 files changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/qpid/java/jca/build.xml b/qpid/java/jca/build.xml
-index 934514a..3f34cc9 100644
---- a/qpid/java/jca/build.xml
-+++ b/qpid/java/jca/build.xml
-@@ -29,9 +29,18 @@
-
-
-
--
--
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-
-+
-
-
-
---
-1.7.1
-
-From cd6505a2a66349390be44712f632d72fcaa66ed7 Mon Sep 17 00:00:00 2001
-From: Rajith Muditha Attapattu
-Date: Thu, 6 Sep 2012 14:41:29 +0000
-Subject: [PATCH 04/19] Bug 851574, QPID-4288: The pid and platform info are now fetched in a static block
- and the cached value is returned.
-
-git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1381625 13f79535-47bb-0310-9956-ffa450edef68
----
- .../qpid/properties/ConnectionStartProperties.java | 27 ++++++++++++++------
- 1 files changed, 19 insertions(+), 8 deletions(-)
-
-diff --git a/qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java b/qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
-index 15c144b..59a1b6c 100644
---- a/qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
-+++ b/qpid/java/common/src/main/java/org/apache/qpid/properties/ConnectionStartProperties.java
-@@ -49,7 +49,11 @@ public class ConnectionStartProperties
-
- public static final String SESSION_FLOW = "qpid.session_flow";
-
-- public static int getPID()
-+ public static int _pid;
-+
-+ public static final String _platformInfo;
-+
-+ static
- {
- RuntimeMXBean rtb = ManagementFactory.getRuntimeMXBean();
- String processName = rtb.getName();
-@@ -57,23 +61,20 @@ public class ConnectionStartProperties
- {
- try
- {
-- return Integer.parseInt(processName.substring(0,processName.indexOf('@')));
-+ _pid = Integer.parseInt(processName.substring(0,processName.indexOf('@')));
- }
- catch(Exception e)
- {
- LOGGER.warn("Unable to get the PID due to error",e);
-- return -1;
-+ _pid = -1;
- }
- }
- else
- {
- LOGGER.warn("Unable to get the PID due to unsupported format : " + processName);
-- return -1;
-+ _pid = -1;
- }
-- }
-
-- public static String getPlatformInfo()
-- {
- StringBuilder fullSystemInfo = new StringBuilder(System.getProperty("java.runtime.name"));
- fullSystemInfo.append(", ");
- fullSystemInfo.append(System.getProperty("java.runtime.version"));
-@@ -88,6 +89,16 @@ public class ConnectionStartProperties
- fullSystemInfo.append(", ");
- fullSystemInfo.append(System.getProperty("sun.os.patch.level"));
-
-- return fullSystemInfo.toString();
-+ _platformInfo = fullSystemInfo.toString();
-+ }
-+
-+ public static int getPID()
-+ {
-+ return _pid;
-+ }
-+
-+ public static String getPlatformInfo()
-+ {
-+ return _platformInfo;
- }
- }
---
-1.7.1
-
-From fd604472e4dcc8b5e7042503450a9f81c572dc6a Mon Sep 17 00:00:00 2001
-From: Charles E. Rolke
-Date: Sun, 15 Jul 2012 10:17:26 +0000
-Subject: [PATCH 05/19] QPID-3892 C++ broker add routing key wildcard support to Acl 'publish exchange' lookups. Although this patch does not address the original issue's regex request it provides the desired functionality in a more comprehensive manner.
-
-* Acl publish exchange rules may specify routing keys using the topic exchange syntax with '*' and '#' wildcard match tokens.
-* Acl lookups hook in to the broker's topic exchange key match code to perform the wildcard match.
-* Acl rules written using the old Acl wildcard syntax (with a single trailing '*') will continue to work the same as before.
-
-git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1361678 13f79535-47bb-0310-9956-ffa450edef68
----
- qpid/cpp/src/qpid/acl/AclData.cpp | 81 ++++++++++------------
- qpid/cpp/src/qpid/acl/AclData.h | 38 +++++++++--
- qpid/cpp/src/qpid/acl/AclReader.cpp | 29 ++++++--
- qpid/cpp/src/qpid/acl/AclReader.h | 1 +
- qpid/cpp/src/qpid/acl/AclValidator.cpp | 2 +-
- qpid/cpp/src/qpid/acl/AclValidator.h | 2 +-
- qpid/cpp/src/tests/acl.py | 120 +++++++++++++++++++++++++++++++-
- 7 files changed, 215 insertions(+), 58 deletions(-)
-
-diff --git a/qpid/cpp/src/qpid/acl/AclData.cpp b/qpid/cpp/src/qpid/acl/AclData.cpp
-index da7f240..a07176d 100644
---- a/qpid/cpp/src/qpid/acl/AclData.cpp
-+++ b/qpid/cpp/src/qpid/acl/AclData.cpp
-@@ -305,7 +305,9 @@ namespace acl {
- // lookup
- //
- // The ACL main business logic function of matching rules and declaring
-- // an allow or deny result.
-+ // an allow or deny result. This lookup is the fastpath per-message
-+ // lookup to verify if a user is allowed to publish to an exchange with
-+ // a given key.
- //
- AclResult AclData::lookup(
- const std::string& id,
-@@ -331,7 +333,8 @@ namespace acl {
-
- if (itrRule != actionList[action][objType]->end() )
- {
-- //loop the vector
-+ // Found a rule list for this user-action-object set.
-+ // Search the rule list for a matching rule.
- ruleSetItr rsItr = itrRule->second.end();
- for (int cnt = itrRule->second.size(); cnt != 0; cnt--)
- {
-@@ -339,56 +342,46 @@ namespace acl {
-
- QPID_LOG(debug, "ACL: checking rule " << rsItr->toString());
-
-- // loop the names looking for match
-+ // Search on exchange name and routing key only if specfied in rule.
- bool match =true;
-- for (specPropertyMapItr pMItr = rsItr->props.begin();
-- (pMItr != rsItr->props.end()) && match;
-- pMItr++)
-+ if (rsItr->pubExchNameInRule)
- {
-- //match name is exists first
-- switch (pMItr->first)
-+ if (matchProp(rsItr->pubExchName, name))
- {
-- case acl::SPECPROP_NAME:
-- if (matchProp(pMItr->second, name))
-- {
-- QPID_LOG(debug, "ACL: lookup exchange name '"
-- << name << "' matched with rule name '"
-- << pMItr->second << "'");
--
-- }
-- else
-- {
-- match= false;
-- QPID_LOG(debug, "ACL: lookup exchange name '"
-- << name << "' did not match with rule name '"
-- << pMItr->second << "'");
-- }
-- break;
-+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup exchange name '"
-+ << name << "' matched with rule name '"
-+ << rsItr->pubExchName << "'");
-
-- case acl::SPECPROP_ROUTINGKEY:
-- if (matchProp(pMItr->second, routingKey))
-- {
-- QPID_LOG(debug, "ACL: lookup key name '"
-- << routingKey << "' matched with rule routing key '"
-- << pMItr->second << "'");
-- }
-- else
-- {
-- match= false;
-- QPID_LOG(debug, "ACL: lookup key name '"
-- << routingKey << "' did not match with rule routing key '"
-- << pMItr->second << "'");
-- }
-- break;
-+ }
-+ else
-+ {
-+ match= false;
-+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup exchange name '"
-+ << name << "' did not match with rule name '"
-+ << rsItr->pubExchName << "'");
-+ }
-+ }
-
-- default:
-- // Don't care
-- break;
-- };
-+ if (match && rsItr->pubRoutingKeyInRule)
-+ {
-+ if (rsItr->matchRoutingKey(routingKey))
-+ {
-+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
-+ << routingKey << "' matched with rule routing key '"
-+ << rsItr->pubRoutingKey << "'");
-+ }
-+ else
-+ {
-+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
-+ << routingKey << "' did not match with rule routing key '"
-+ << rsItr->pubRoutingKey << "'");
-+ match = false;
-+ }
- }
-+
- if (match){
- aclresult = rsItr->ruleMode;
-- QPID_LOG(debug,"ACL: Successful match, the decision is:"
-+ QPID_LOG(debug,"ACL: Rule: " << rsItr->rawRuleNum << " Successful match, the decision is:"
- << AclHelper::getAclResultStr(aclresult));
- return aclresult;
- }
-diff --git a/qpid/cpp/src/qpid/acl/AclData.h b/qpid/cpp/src/qpid/acl/AclData.h
-index 1c1cb3e..ca0a676 100644
---- a/qpid/cpp/src/qpid/acl/AclData.h
-+++ b/qpid/cpp/src/qpid/acl/AclData.h
-@@ -21,6 +21,9 @@
- */
-
- #include "qpid/broker/AclModule.h"
-+#include "AclTopicMatch.h"
-+#include "qpid/log/Statement.h"
-+#include "boost/shared_ptr.hpp"
- #include
- #include
-
-@@ -48,18 +51,29 @@ public:
- // A single ACL file entry may create many rule entries in
- // many ruleset vectors.
- //
-- struct rule {
-+ struct Rule {
-+ typedef broker::TopicExchange::TopicExchangeTester topicTester;
-
- int rawRuleNum; // rule number in ACL file
- qpid::acl::AclResult ruleMode; // combined allow/deny log/nolog
- specPropertyMap props; //
-+ bool pubRoutingKeyInRule;
-+ std::string pubRoutingKey;
-+ boost::shared_ptr pTTest;
-+ bool pubExchNameInRule;
-+ std::string pubExchName;
-
--
-- rule (int ruleNum, qpid::acl::AclResult res, specPropertyMap& p) :
-+ Rule (int ruleNum, qpid::acl::AclResult res, specPropertyMap& p) :
- rawRuleNum(ruleNum),
- ruleMode(res),
-- props(p)
-- {};
-+ props(p),
-+ pubRoutingKeyInRule(false),
-+ pubRoutingKey(),
-+ pTTest(boost::shared_ptr(new topicTester())),
-+ pubExchNameInRule(false),
-+ pubExchName()
-+ {}
-+
-
- std::string toString () const {
- std::ostringstream ruleStr;
-@@ -76,9 +90,21 @@ public:
- ruleStr << " }]";
- return ruleStr.str();
- }
-+
-+ void addTopicTest(const std::string& pattern) {
-+ pTTest->addBindingKey(broker::TopicExchange::normalize(pattern));
-+ }
-+
-+ // Topic Exchange tester
-+ // return true if any bindings match 'pattern'
-+ bool matchRoutingKey(const std::string& pattern) const
-+ {
-+ topicTester::BindingVec bv;
-+ return pTTest->findMatches(pattern, bv);
-+ }
- };
-
-- typedef std::vector ruleSet;
-+ typedef std::vector ruleSet;
- typedef ruleSet::const_iterator ruleSetItr;
- typedef std::map actionObject; // user
- typedef actionObject::iterator actObjItr;
-diff --git a/qpid/cpp/src/qpid/acl/AclReader.cpp b/qpid/cpp/src/qpid/acl/AclReader.cpp
-index 0830f3f..f9be49b 100644
---- a/qpid/cpp/src/qpid/acl/AclReader.cpp
-+++ b/qpid/cpp/src/qpid/acl/AclReader.cpp
-@@ -101,7 +101,7 @@ namespace acl {
- << AclHelper::getAclResultStr(d->decisionMode));
- foundmode = true;
- } else {
-- AclData::rule rule(cnt, (*i)->res, (*i)->props);
-+ AclData::Rule rule(cnt, (*i)->res, (*i)->props);
-
- // Action -> Object -> map set >
- std::ostringstream actionstr;
-@@ -110,8 +110,27 @@ namespace acl {
- (*i)->actionAll ? acnt++ : acnt = acl::ACTIONSIZE) {
-
- if (acnt == acl::ACT_PUBLISH)
-+ {
- d->transferAcl = true; // we have transfer ACL
--
-+ // For Publish the only object should be Exchange
-+ // and the only property should be routingkey.
-+ // Go through the rule properties and find the name and the key.
-+ // If found then place them specially for the lookup engine.
-+ for (pmCitr pItr=(*i)->props.begin(); pItr!=(*i)->props.end(); pItr++) {
-+ if (acl::SPECPROP_ROUTINGKEY == pItr->first)
-+ {
-+ rule.pubRoutingKeyInRule = true;
-+ rule.pubRoutingKey = (std::string)pItr->second;
-+ rule.addTopicTest(rule.pubRoutingKey);
-+ break;
-+ }
-+ if (acl::SPECPROP_NAME == pItr->first)
-+ {
-+ rule.pubExchNameInRule = true;
-+ rule.pubExchName = pItr->second;
-+ }
-+ }
-+ }
- actionstr << AclHelper::getActionStr((Action) acnt) << ",";
-
- //find the Action, create if not exist
-@@ -285,7 +304,7 @@ namespace acl {
- if (ws) {
- ret = true;
- } else {
-- errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
-+ errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
- << ", Non-continuation line must start with \"group\" or \"acl\".";
- ret = false;
- }
-@@ -330,7 +349,7 @@ namespace acl {
- } else {
- const unsigned minimumSize = (cont ? 2 : 3);
- if (toksSize < minimumSize) {
-- errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
-+ errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
- << ", Insufficient tokens for group definition.";
- return false;
- }
-@@ -479,7 +498,7 @@ namespace acl {
- nvPair propNvp = splitNameValuePair(toks[i]);
- if (propNvp.second.size() == 0) {
- errorStream << ACL_FORMAT_ERR_LOG_PREFIX << "Line : " << lineNumber
-- <<", Badly formed property name-value pair \""
-+ <<", Badly formed property name-value pair \""
- << propNvp.first << "\". (Must be name=value)";
- return false;
- }
-diff --git a/qpid/cpp/src/qpid/acl/AclReader.h b/qpid/cpp/src/qpid/acl/AclReader.h
-index 730013f..6351c1e 100644
---- a/qpid/cpp/src/qpid/acl/AclReader.h
-+++ b/qpid/cpp/src/qpid/acl/AclReader.h
-@@ -26,6 +26,7 @@
- #include
- #include
- #include
-+#include
- #include "qpid/acl/AclData.h"
- #include "qpid/broker/AclModule.h"
-
-diff --git a/qpid/cpp/src/qpid/acl/AclValidator.cpp b/qpid/cpp/src/qpid/acl/AclValidator.cpp
-index 49bb65d..85f0f7c 100644
---- a/qpid/cpp/src/qpid/acl/AclValidator.cpp
-+++ b/qpid/cpp/src/qpid/acl/AclValidator.cpp
-@@ -131,7 +131,7 @@ namespace acl {
- boost::bind(&AclValidator::validateRule, this, _1));
- }
-
-- void AclValidator::validateRule(qpid::acl::AclData::rule& rule){
-+ void AclValidator::validateRule(qpid::acl::AclData::Rule& rule){
- std::for_each(rule.props.begin(),
- rule.props.end(),
- boost::bind(&AclValidator::validateProperty, this, _1));
-diff --git a/qpid/cpp/src/qpid/acl/AclValidator.h b/qpid/cpp/src/qpid/acl/AclValidator.h
-index f85c241..76eb222 100644
---- a/qpid/cpp/src/qpid/acl/AclValidator.h
-+++ b/qpid/cpp/src/qpid/acl/AclValidator.h
-@@ -71,7 +71,7 @@ class AclValidator {
- public:
-
- void validateRuleSet(std::pair& rules);
-- void validateRule(qpid::acl::AclData::rule& rule);
-+ void validateRule(qpid::acl::AclData::Rule& rule);
- void validateProperty(std::pair& prop);
- void validate(boost::shared_ptr d);
- AclValidator();
-diff --git a/qpid/cpp/src/tests/acl.py b/qpid/cpp/src/tests/acl.py
-index 663af3e..0e096a6 100755
---- a/qpid/cpp/src/tests/acl.py
-+++ b/qpid/cpp/src/tests/acl.py
-@@ -310,7 +310,7 @@ class ACLTests(TestBase010):
- self.fail("ACL should allow queue create request");
- self.fail("Error during queue create request");
-
--
-+
-
- def test_user_realm(self):
- """
-@@ -1537,6 +1537,124 @@ class ACLTests(TestBase010):
-
-
- #=====================================
-+ # QMF Topic Exchange tests
-+ #=====================================
-+
-+ def test_qmf_topic_exchange_tests(self):
-+ """
-+ Test using QMF method hooks into ACL logic
-+ """
-+ aclf = self.get_acl_file()
-+ aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
-+ aclf.write('acl allow-log anonymous create queue\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qmf.*\n')
-+ aclf.write('acl allow-log anonymous all exchange name=amq.direct\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qpid.management\n')
-+ aclf.write('acl allow-log anonymous access method name=*\n')
-+ aclf.write('# end hack alert\n')
-+ aclf.write('acl allow-log uPlain1@COMPANY publish exchange name=X routingkey=ab.cd.e\n')
-+ aclf.write('acl allow-log uPlain2@COMPANY publish exchange name=X routingkey=.\n')
-+ aclf.write('acl allow-log uStar1@COMPANY publish exchange name=X routingkey=a.*.b\n')
-+ aclf.write('acl allow-log uStar2@COMPANY publish exchange name=X routingkey=*.x\n')
-+ aclf.write('acl allow-log uStar3@COMPANY publish exchange name=X routingkey=x.x.*\n')
-+ aclf.write('acl allow-log uHash1@COMPANY publish exchange name=X routingkey=a.#.b\n')
-+ aclf.write('acl allow-log uHash2@COMPANY publish exchange name=X routingkey=a.#\n')
-+ aclf.write('acl allow-log uHash3@COMPANY publish exchange name=X routingkey=#.a\n')
-+ aclf.write('acl allow-log uHash4@COMPANY publish exchange name=X routingkey=a.#.b.#.c\n')
-+ aclf.write('acl allow-log uMixed1@COMPANY publish exchange name=X routingkey=*.x.#.y\n')
-+ aclf.write('acl allow-log uMixed2@COMPANY publish exchange name=X routingkey=a.#.b.*\n')
-+ aclf.write('acl allow-log uMixed3@COMPANY publish exchange name=X routingkey=*.*.*.#\n')
-+
-+ aclf.write('acl allow-log all publish exchange name=X routingkey=MN.OP.Q\n')
-+ aclf.write('acl allow-log all publish exchange name=X routingkey=M.*.N\n')
-+ aclf.write('acl allow-log all publish exchange name=X routingkey=M.#.N\n')
-+ aclf.write('acl allow-log all publish exchange name=X routingkey=*.M.#.N\n')
-+
-+ aclf.write('acl deny-log all all\n')
-+ aclf.close()
-+
-+ result = self.reload_acl()
-+ if (result):
-+ self.fail(result)
-+
-+ # aclKey: "ab.cd.e"
-+ self.LookupPublish("uPlain1@COMPANY", "X", "ab.cd.e", "allow-log")
-+ self.LookupPublish("uPlain1@COMPANY", "X", "abx.cd.e", "deny-log")
-+ self.LookupPublish("uPlain1@COMPANY", "X", "ab.cd", "deny-log")
-+ self.LookupPublish("uPlain1@COMPANY", "X", "ab.cd..e.", "deny-log")
-+ self.LookupPublish("uPlain1@COMPANY", "X", "ab.cd.e.", "deny-log")
-+ self.LookupPublish("uPlain1@COMPANY", "X", ".ab.cd.e", "deny-log")
-+ # aclKey: "."
-+ self.LookupPublish("uPlain2@COMPANY", "X", ".", "allow-log")
-+
-+ # aclKey: "a.*.b"
-+ self.LookupPublish("uStar1@COMPANY", "X", "a.xx.b", "allow-log")
-+ self.LookupPublish("uStar1@COMPANY", "X", "a.b", "deny-log")
-+ # aclKey: "*.x"
-+ self.LookupPublish("uStar2@COMPANY", "X", "y.x", "allow-log")
-+ self.LookupPublish("uStar2@COMPANY", "X", ".x", "allow-log")
-+ self.LookupPublish("uStar2@COMPANY", "X", "x", "deny-log")
-+ # aclKey: "x.x.*"
-+ self.LookupPublish("uStar3@COMPANY", "X", "x.x.y", "allow-log")
-+ self.LookupPublish("uStar3@COMPANY", "X", "x.x.", "allow-log")
-+ self.LookupPublish("uStar3@COMPANY", "X", "x.x", "deny-log")
-+ self.LookupPublish("uStar3@COMPANY", "X", "q.x.y", "deny-log")
-+
-+ # aclKey: "a.#.b"
-+ self.LookupPublish("uHash1@COMPANY", "X", "a.b", "allow-log")
-+ self.LookupPublish("uHash1@COMPANY", "X", "a.x.b", "allow-log")
-+ self.LookupPublish("uHash1@COMPANY", "X", "a..x.y.zz.b", "allow-log")
-+ self.LookupPublish("uHash1@COMPANY", "X", "a.b.", "deny-log")
-+ self.LookupPublish("uHash1@COMPANY", "X", "q.x.b", "deny-log")
-+
-+ # aclKey: "a.#"
-+ self.LookupPublish("uHash2@COMPANY", "X", "a", "allow-log")
-+ self.LookupPublish("uHash2@COMPANY", "X", "a.b", "allow-log")
-+ self.LookupPublish("uHash2@COMPANY", "X", "a.b.c", "allow-log")
-+
-+ # aclKey: "#.a"
-+ self.LookupPublish("uHash3@COMPANY", "X", "a", "allow-log")
-+ self.LookupPublish("uHash3@COMPANY", "X", "x.y.a", "allow-log")
-+
-+ # aclKey: "a.#.b.#.c"
-+ self.LookupPublish("uHash4@COMPANY", "X", "a.b.c", "allow-log")
-+ self.LookupPublish("uHash4@COMPANY", "X", "a.x.b.y.c", "allow-log")
-+ self.LookupPublish("uHash4@COMPANY", "X", "a.x.x.b.y.y.c", "allow-log")
-+
-+ # aclKey: "*.x.#.y"
-+ self.LookupPublish("uMixed1@COMPANY", "X", "a.x.y", "allow-log")
-+ self.LookupPublish("uMixed1@COMPANY", "X", "a.x.p.qq.y", "allow-log")
-+ self.LookupPublish("uMixed1@COMPANY", "X", "a.a.x.y", "deny-log")
-+ self.LookupPublish("uMixed1@COMPANY", "X", "aa.x.b.c", "deny-log")
-+
-+ # aclKey: "a.#.b.*"
-+ self.LookupPublish("uMixed2@COMPANY", "X", "a.b.x", "allow-log")
-+ self.LookupPublish("uMixed2@COMPANY", "X", "a.x.x.x.b.x", "allow-log")
-+
-+ # aclKey: "*.*.*.#"
-+ self.LookupPublish("uMixed3@COMPANY", "X", "x.y.z", "allow-log")
-+ self.LookupPublish("uMixed3@COMPANY", "X", "x.y.z.a.b.c", "allow-log")
-+ self.LookupPublish("uMixed3@COMPANY", "X", "x.y", "deny-log")
-+ self.LookupPublish("uMixed3@COMPANY", "X", "x", "deny-log")
-+
-+ # Repeat the keys with wildcard user spec
-+ self.LookupPublish("uPlain1@COMPANY", "X", "MN.OP.Q", "allow-log")
-+ self.LookupPublish("uStar1@COMPANY" , "X", "M.xx.N", "allow-log")
-+ self.LookupPublish("uHash1@COMPANY" , "X", "M.N", "allow-log")
-+ self.LookupPublish("uHash1@COMPANY" , "X", "M.x.N", "allow-log")
-+ self.LookupPublish("uHash1@COMPANY" , "X", "M..x.y.zz.N", "allow-log")
-+ self.LookupPublish("uMixed1@COMPANY", "X", "a.M.N", "allow-log")
-+ self.LookupPublish("uMixed1@COMPANY", "X", "a.M.p.qq.N", "allow-log")
-+
-+ self.LookupPublish("dev@QPID", "X", "MN.OP.Q", "allow-log")
-+ self.LookupPublish("dev@QPID", "X", "M.xx.N", "allow-log")
-+ self.LookupPublish("dev@QPID", "X", "M.N", "allow-log")
-+ self.LookupPublish("dev@QPID", "X", "M.x.N", "allow-log")
-+ self.LookupPublish("dev@QPID", "X", "M..x.y.zz.N", "allow-log")
-+ self.LookupPublish("dev@QPID", "X", "a.M.N", "allow-log")
-+ self.LookupPublish("dev@QPID", "X", "a.M.p.qq.N", "allow-log")
-+
-+ #=====================================
- # Connection limits
- #=====================================
-
---
-1.7.1
-
-From d9f282af80d57bdb01a90966178839da5cbf4021 Mon Sep 17 00:00:00 2001
-From: Charles E. Rolke
-Date: Sun, 15 Jul 2012 11:52:47 -0500
-Subject: [PATCH 06/19] QPID-4107 r1361334 type in file name
-
-git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1361733 13f79535-47bb-0310-9956-ffa450edef68
-
-Conflicts:
-
- qpid/cpp/src/ha.mk
----
- qpid/cpp/src/ha.mk | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/qpid/cpp/src/ha.mk b/qpid/cpp/src/ha.mk
-index 96a3d87..85dd9dd 100644
---- a/qpid/cpp/src/ha.mk
-+++ b/qpid/cpp/src/ha.mk
-@@ -23,7 +23,7 @@
- dmoduleexec_LTLIBRARIES += ha.la
-
- ha_la_SOURCES = \
-- qpid/ha/AlternateExchangeSetter.h \
-+ qpid/ha/AlternateExchangeSetter.h \
- qpid/ha/Backup.cpp \
- qpid/ha/Backup.h \
- qpid/ha/BackupConnectionExcluder.h \
---
-1.7.1
-
-From af60f8280c721dcee9b03b23bff4d89a9d61cf13 Mon Sep 17 00:00:00 2001
-From: Charles E. Rolke
-Date: Mon, 16 Jul 2012 12:58:29 +0000
-Subject: [PATCH 07/19] QPID-3892 add missing file
-
-git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1362014 13f79535-47bb-0310-9956-ffa450edef68
----
- qpid/cpp/src/qpid/acl/AclTopicMatch.h | 89 +++++++++++++++++++++++++++++++++
- 1 files changed, 89 insertions(+), 0 deletions(-)
- create mode 100644 qpid/cpp/src/qpid/acl/AclTopicMatch.h
-
-diff --git a/qpid/cpp/src/qpid/acl/AclTopicMatch.h b/qpid/cpp/src/qpid/acl/AclTopicMatch.h
-new file mode 100644
-index 0000000..486c229
---- /dev/null
-+++ b/qpid/cpp/src/qpid/acl/AclTopicMatch.h
-@@ -0,0 +1,89 @@
-+#ifndef QPID_ACL_TOPIC_MATCH_H
-+#define QPID_ACL_TOPIC_MATCH_H
-+
-+/*
-+ *
-+ * Copyright (c) 2006 The Apache Software Foundation
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#include "qpid/broker/TopicKeyNode.h"
-+#include "qpid/broker/TopicExchange.h"
-+#include "qpid/log/Statement.h"
-+#include "boost/shared_ptr.hpp"
-+#include
-+#include
-+
-+namespace qpid {
-+namespace broker {
-+
-+// Class for executing topic exchange routing key matching rules in
-+// Acl code the allows or denies users publishing to an exchange.
-+class TopicExchange::TopicExchangeTester {
-+
-+class boundNode;
-+
-+public:
-+ typedef std::vector BindingVec;
-+ typedef TopicKeyNode TestBindingNode;
-+
-+private:
-+ // Target class to be bound into topic key tree
-+ class boundNode {
-+ public:
-+ BindingVec bindingVector;
-+ };
-+
-+ // Acl binding trees contain only one node each.
-+ // When the iterator sees it then the node matches the caller's spec.
-+ class TestFinder : public TestBindingNode::TreeIterator {
-+ public:
-+ TestFinder(BindingVec& m) : bv(m), found(false) {};
-+ ~TestFinder() {};
-+ bool visit(TestBindingNode& /*node*/) {
-+ assert(!found);
-+ found = true;
-+ return true;
-+ }
-+ BindingVec& bv;
-+ bool found;
-+ };
-+
-+public:
-+ TopicExchangeTester() {};
-+ ~TopicExchangeTester() {};
-+ bool addBindingKey(const std::string& bKey) {
-+ std::string routingPattern = normalize(bKey);
-+ boundNode *mbn = bindingTree.add(routingPattern);
-+ if (mbn) {
-+ // push a dummy binding to mark this node as "non-leaf"
-+ mbn->bindingVector.push_back(true);
-+ return true;
-+ }
-+ return false;
-+ }
-+
-+ bool findMatches(const std::string& rKey, BindingVec& matches) {
-+ TestFinder testFinder(matches);
-+ bindingTree.iterateMatch( rKey, testFinder );
-+ return testFinder.found;
-+ }
-+
-+private:
-+ TestBindingNode bindingTree;
-+};
-+}} // namespace qpid::broker
-+
-+#endif // QPID_ACL_TOPIC_MATCH_H
---
-1.7.1
-
-From c68822714d4da4bee808e19f4b10145b7f4bdcae Mon Sep 17 00:00:00 2001
-From: Charles E. Rolke
-Date: Wed, 15 Aug 2012 14:14:57 +0000
-Subject: [PATCH 08/19] NO-JIRA Initialize variable before its use.
-
-git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1373429 13f79535-47bb-0310-9956-ffa450edef68
----
- qpid/cpp/src/tests/acl.py | 1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
-
-diff --git a/qpid/cpp/src/tests/acl.py b/qpid/cpp/src/tests/acl.py
-index 0e096a6..23886d5 100755
---- a/qpid/cpp/src/tests/acl.py
-+++ b/qpid/cpp/src/tests/acl.py
-@@ -119,6 +119,7 @@ class ACLTests(TestBase010):
- def LookupPublish(self, userName, exchName, keyName, expectedResult):
- result = self.acl_lookupPublish(userName, exchName, keyName)
- if (result['result'] != expectedResult):
-+ suffix = ', [ERROR: Expected= ' + expectedResult
- if (result['result'] is None):
- suffix = suffix + ', Exception= ' + result['text'] + ']'
- else:
---
-1.7.1
-
-From 1a5a36a7d839c32d2e6edfe739de379624f3b3ba Mon Sep 17 00:00:00 2001
-From: Charles E. Rolke
-Date: Mon, 20 Aug 2012 20:09:43 +0000
-Subject: [PATCH 09/19] QPID-4230 (review 6645) Username substition keywords in Acl file.
-
-git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1375195 13f79535-47bb-0310-9956-ffa450edef68
----
- qpid/cpp/src/qpid/acl/AclData.cpp | 183 +++++++++++-
- qpid/cpp/src/qpid/acl/AclData.h | 15 +-
- qpid/cpp/src/qpid/acl/AclReader.cpp | 9 +
- qpid/cpp/src/qpid/broker/AclModule.h | 4 +-
- qpid/cpp/src/tests/acl.py | 540 ++++++++++++++++++++++++++++++++++
- 5 files changed, 738 insertions(+), 13 deletions(-)
-
-diff --git a/qpid/cpp/src/qpid/acl/AclData.cpp b/qpid/cpp/src/qpid/acl/AclData.cpp
-index a07176d..7c14d09 100644
---- a/qpid/cpp/src/qpid/acl/AclData.cpp
-+++ b/qpid/cpp/src/qpid/acl/AclData.cpp
-@@ -25,6 +25,13 @@ namespace qpid {
- namespace acl {
-
- //
-+ // Instantiate the substitution keyword string
-+ //
-+ const std::string AclData::USER_SUBSTITUTION_KEYWORD = "${user}";
-+ const std::string AclData::DOMAIN_SUBSTITUTION_KEYWORD = "${domain}";
-+ const std::string AclData::USERDOMAIN_SUBSTITUTION_KEYWORD = "${userdomain}";
-+
-+ //
- // constructor
- //
- AclData::AclData():
-@@ -147,7 +154,17 @@ namespace acl {
- // the calling args and not in the param map.
- if (rulePropMapItr->first == acl::SPECPROP_NAME)
- {
-- if (matchProp(rulePropMapItr->second, name))
-+ // substitute user name into object name
-+ bool result;
-+ if (rsItr->ruleHasUserSub[PROP_NAME]) {
-+ std::string sName(rulePropMapItr->second);
-+ substituteUserId(sName, id);
-+ result = matchProp(sName, name);
-+ } else {
-+ result = matchProp(rulePropMapItr->second, name);
-+ }
-+
-+ if (result)
- {
- QPID_LOG(debug, "ACL: lookup name '" << name
- << "' matched with rule name '"
-@@ -222,7 +239,20 @@ namespace acl {
- break;
-
- default:
-- if (matchProp(rulePropMapItr->second, lookupParamItr->second))
-+ bool result;
-+ if ((SPECPROP_ALTERNATE == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_ALTERNATE]) ||
-+ (SPECPROP_ROUTINGKEY == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_ROUTINGKEY]) ||
-+ (SPECPROP_QUEUENAME == rulePropMapItr->first && rsItr->ruleHasUserSub[PROP_QUEUENAME]))
-+ {
-+ // These properties are allowed to have username substitution
-+ std::string sName(rulePropMapItr->second);
-+ substituteUserId(sName, id);
-+ result = matchProp(sName, lookupParamItr->second);
-+ } else {
-+ result = matchProp(rulePropMapItr->second, lookupParamItr->second);
-+ }
-+
-+ if (result)
- {
- QPID_LOG(debug, "ACL: the pair("
- << AclHelper::getPropertyStr(lookupParamItr->first)
-@@ -346,7 +376,18 @@ namespace acl {
- bool match =true;
- if (rsItr->pubExchNameInRule)
- {
-- if (matchProp(rsItr->pubExchName, name))
-+ // substitute user name into object name
-+ bool result;
-+
-+ if (rsItr->ruleHasUserSub[PROP_NAME]) {
-+ std::string sName(rsItr->pubExchName);
-+ substituteUserId(sName, id);
-+ result = matchProp(sName, name);
-+ } else {
-+ result = matchProp(rsItr->pubExchName, name);
-+ }
-+
-+ if (result)
- {
- QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup exchange name '"
- << name << "' matched with rule name '"
-@@ -364,18 +405,40 @@ namespace acl {
-
- if (match && rsItr->pubRoutingKeyInRule)
- {
-- if (rsItr->matchRoutingKey(routingKey))
-+ if ((routingKey.find(USER_SUBSTITUTION_KEYWORD, 0) != std::string::npos) ||
-+ (routingKey.find(DOMAIN_SUBSTITUTION_KEYWORD, 0) != std::string::npos) ||
-+ (routingKey.find(USERDOMAIN_SUBSTITUTION_KEYWORD, 0) != std::string::npos))
- {
-- QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
-- << routingKey << "' matched with rule routing key '"
-- << rsItr->pubRoutingKey << "'");
-+ // The user is not allowed to present a routing key with the substitution key in it
-+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum <<
-+ " User-specified routing key has substitution wildcard:" << routingKey
-+ << ". Rule match prohibited.");
-+ match = false;
- }
- else
- {
-- QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
-- << routingKey << "' did not match with rule routing key '"
-- << rsItr->pubRoutingKey << "'");
-- match = false;
-+ bool result;
-+ if (rsItr->ruleHasUserSub[PROP_ROUTINGKEY]) {
-+ std::string sKey(routingKey);
-+ substituteKeywords(sKey, id);
-+ result = rsItr->matchRoutingKey(sKey);
-+ } else {
-+ result = rsItr->matchRoutingKey(routingKey);
-+ }
-+
-+ if (result)
-+ {
-+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
-+ << routingKey << "' matched with rule routing key '"
-+ << rsItr->pubRoutingKey << "'");
-+ }
-+ else
-+ {
-+ QPID_LOG(debug, "ACL: Rule: " << rsItr->rawRuleNum << " lookup key name '"
-+ << routingKey << "' did not match with rule routing key '"
-+ << rsItr->pubRoutingKey << "'");
-+ match = false;
-+ }
- }
- }
-
-@@ -501,4 +564,102 @@ namespace acl {
- return true;
- }
-
-+ const std::string DOMAIN_SEPARATOR("@");
-+ const std::string PERIOD(".");
-+ const std::string UNDERSCORE("_");
-+ //
-+ // substituteString
-+ // Given a name string from an Acl rule, substitute the replacement into it
-+ // wherever the placeholder directs.
-+ //
-+ void AclData::substituteString(std::string& targetString,
-+ const std::string& placeholder,
-+ const std::string& replacement)
-+ {
-+ assert (!placeholder.empty());
-+ if (placeholder.empty())
-+ return;
-+ size_t start_pos(0);
-+ while((start_pos = targetString.find(placeholder, start_pos)) != std::string::npos)
-+ {
-+ targetString.replace(start_pos, placeholder.length(), replacement);
-+ start_pos += replacement.length();
-+ }
-+ }
-+
-+
-+ //
-+ // normalizeUserId
-+ // Given a name string return it in a form usable as topic keys:
-+ // change "@" and "." to "_".
-+ //
-+ std::string AclData::normalizeUserId(const std::string& userId)
-+ {
-+ std::string normalId(userId);
-+ substituteString(normalId, DOMAIN_SEPARATOR, UNDERSCORE);
-+ substituteString(normalId, PERIOD, UNDERSCORE);
-+ return normalId;
-+ }
-+
-+
-+ //
-+ // substituteUserId
-+ // Given an Acl rule and an authenticated userId
-+ // do the keyword substitutions on the rule.
-+ //
-+ void AclData::AclData::substituteUserId(std::string& ruleString,
-+ const std::string& userId)
-+ {
-+ size_t locDomSeparator(0);
-+ std::string user("");
-+ std::string domain("");
-+ std::string userdomain = normalizeUserId(userId);
-+
-+ locDomSeparator = userId.find(DOMAIN_SEPARATOR);
-+ if (std::string::npos == locDomSeparator) {
-+ // "@" not found. There's just a user name
-+ user = normalizeUserId(userId);
-+ } else {
-+ // "@" found, split the names. Domain may be blank.
-+ user = normalizeUserId(userId.substr(0,locDomSeparator));
-+ domain = normalizeUserId(userId.substr(locDomSeparator+1));
-+ }
-+
-+ substituteString(ruleString, USER_SUBSTITUTION_KEYWORD, user);
-+ substituteString(ruleString, DOMAIN_SUBSTITUTION_KEYWORD, domain);
-+ substituteString(ruleString, USERDOMAIN_SUBSTITUTION_KEYWORD, userdomain);
-+ }
-+
-+
-+ //
-+ // substituteKeywords
-+ // Given an Acl rule and an authenticated userId
-+ // do reverse keyword substitutions on the rule.
-+ // That is, replace the normalized name in the rule string with
-+ // the keyword that represents it. This stragegy is used for
-+ // topic key lookups where the keyword string proper is in the
-+ // topic key search tree.
-+ //
-+ void AclData::AclData::substituteKeywords(std::string& ruleString,
-+ const std::string& userId)
-+ {
-+ size_t locDomSeparator(0);
-+ std::string user("");
-+ std::string domain("");
-+ std::string userdomain = normalizeUserId(userId);
-+
-+ locDomSeparator = userId.find(DOMAIN_SEPARATOR);
-+ if (std::string::npos == locDomSeparator) {
-+ // "@" not found. There's just a user name
-+ user = normalizeUserId(userId);
-+ } else {
-+ // "@" found, split the names
-+ user = normalizeUserId(userId.substr(0,locDomSeparator));
-+ domain = normalizeUserId(userId.substr(locDomSeparator+1));
-+ }
-+ std::string oRule(ruleString);
-+ substituteString(ruleString, userdomain, USERDOMAIN_SUBSTITUTION_KEYWORD);
-+ substituteString(ruleString, user, USER_SUBSTITUTION_KEYWORD);
-+ substituteString(ruleString, domain, DOMAIN_SUBSTITUTION_KEYWORD);
-+ }
- }}
-diff --git a/qpid/cpp/src/qpid/acl/AclData.h b/qpid/cpp/src/qpid/acl/AclData.h
-index ca0a676..b4b13c4 100644
---- a/qpid/cpp/src/qpid/acl/AclData.h
-+++ b/qpid/cpp/src/qpid/acl/AclData.h
-@@ -62,6 +62,7 @@ public:
- boost::shared_ptr pTTest;
- bool pubExchNameInRule;
- std::string pubExchName;
-+ std::vector ruleHasUserSub;
-
- Rule (int ruleNum, qpid::acl::AclResult res, specPropertyMap& p) :
- rawRuleNum(ruleNum),
-@@ -71,7 +72,8 @@ public:
- pubRoutingKey(),
- pTTest(boost::shared_ptr(new topicTester())),
- pubExchNameInRule(false),
-- pubExchName()
-+ pubExchName(),
-+ ruleHasUserSub(PROPERTYSIZE, false)
- {}
-
-
-@@ -132,6 +134,17 @@ public:
-
- bool matchProp(const std::string & src, const std::string& src1);
- void clear ();
-+ static const std::string USER_SUBSTITUTION_KEYWORD;
-+ static const std::string DOMAIN_SUBSTITUTION_KEYWORD;
-+ static const std::string USERDOMAIN_SUBSTITUTION_KEYWORD;
-+ void substituteString(std::string& targetString,
-+ const std::string& placeholder,
-+ const std::string& replacement);
-+ std::string normalizeUserId(const std::string& userId);
-+ void substituteUserId(std::string& ruleString,
-+ const std::string& userId);
-+ void substituteKeywords(std::string& ruleString,
-+ const std::string& userId);
-
- AclData();
- virtual ~AclData();
-diff --git a/qpid/cpp/src/qpid/acl/AclReader.cpp b/qpid/cpp/src/qpid/acl/AclReader.cpp
-index f9be49b..fae67d0 100644
---- a/qpid/cpp/src/qpid/acl/AclReader.cpp
-+++ b/qpid/cpp/src/qpid/acl/AclReader.cpp
-@@ -103,6 +103,15 @@ namespace acl {
- } else {
- AclData::Rule rule(cnt, (*i)->res, (*i)->props);
-
-+ // Record which properties have the user substitution string
-+ for (pmCitr pItr=rule.props.begin(); pItr!=rule.props.end(); pItr++) {
-+ if ((pItr->second.find(AclData::USER_SUBSTITUTION_KEYWORD, 0) != std::string::npos) ||
-+ (pItr->second.find(AclData::DOMAIN_SUBSTITUTION_KEYWORD, 0) != std::string::npos) ||
-+ (pItr->second.find(AclData::USERDOMAIN_SUBSTITUTION_KEYWORD, 0) != std::string::npos)) {
-+ rule.ruleHasUserSub[pItr->first] = true;
-+ }
-+ }
-+
- // Action -> Object -> map set >
- std::ostringstream actionstr;
- for (int acnt = ((*i)->actionAll ? 0 : (*i)->action);
-diff --git a/qpid/cpp/src/qpid/broker/AclModule.h b/qpid/cpp/src/qpid/broker/AclModule.h
-index f1eb0fc..4caf8ed 100644
---- a/qpid/cpp/src/qpid/broker/AclModule.h
-+++ b/qpid/cpp/src/qpid/broker/AclModule.h
-@@ -78,7 +78,9 @@ namespace acl {
- PROP_SCHEMACLASS,
- PROP_POLICYTYPE,
- PROP_MAXQUEUESIZE,
-- PROP_MAXQUEUECOUNT };
-+ PROP_MAXQUEUECOUNT,
-+ PROPERTYSIZE // PROPERTYSIZE must be last in list
-+ };
-
- // Property used in ACL spec file
- // Note for properties common to file processing/rule storage and to
-diff --git a/qpid/cpp/src/tests/acl.py b/qpid/cpp/src/tests/acl.py
-index 23886d5..102796c 100755
---- a/qpid/cpp/src/tests/acl.py
-+++ b/qpid/cpp/src/tests/acl.py
-@@ -1704,6 +1704,546 @@ class ACLTests(TestBase010):
- result = None
-
-
-+ #=====================================
-+ # User name substitution
-+ #=====================================
-+
-+ def test_user_name_substitution(self):
-+ """
-+ Test name substitution internals, limits, and edge cases.
-+ """
-+ aclf = self.get_acl_file()
-+ aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
-+ aclf.write('acl allow-log anonymous create queue\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qmf.*\n')
-+ aclf.write('acl allow-log anonymous all exchange name=amq.direct\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qpid.management\n')
-+ aclf.write('acl allow-log anonymous access method name=*\n')
-+ aclf.write('# end hack alert\n')
-+ aclf.write('acl allow all create queue name=tmp-${userdomain}\n')
-+ aclf.write('acl allow all create queue name=${userdomain}-tmp\n')
-+ aclf.write('acl allow all create queue name=tmp-${userdomain}-tmp\n')
-+ aclf.write('acl allow all create queue name=tmp-${userdomain}-tmp-${userdomain}\n')
-+ aclf.write('acl allow all create queue name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all access queue name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all purge queue name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all consume queue name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all delete queue name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all create exchange name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all access exchange name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all bind exchange name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all unbind exchange name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all delete exchange name=temp0-${userdomain}\n')
-+ aclf.write('acl allow all publish exchange name=temp0-${userdomain}\n')
-+
-+ aclf.write('acl allow all publish exchange name=X routingkey=${userdomain}.cd.e\n')
-+ aclf.write('acl allow all publish exchange name=X routingkey=a.*.${userdomain}\n')
-+ aclf.write('acl allow all publish exchange name=X routingkey=b.#.${userdomain}\n')
-+ aclf.write('acl allow all publish exchange name=X routingkey=*.${userdomain}.#.y\n')
-+
-+ aclf.write('acl allow all create queue name=user-${user}\n')
-+ aclf.write('acl allow all publish exchange name=U routingkey=${user}.cd.e\n')
-+ aclf.write('acl allow all publish exchange name=U routingkey=a.*.${user}\n')
-+ aclf.write('acl allow all publish exchange name=U routingkey=b.#.${user}\n')
-+ aclf.write('acl allow all publish exchange name=U routingkey=*.${user}.#.y\n')
-+
-+ aclf.write('acl allow all create queue name=domain-${domain}\n')
-+ aclf.write('acl allow all publish exchange name=D routingkey=${domain}.cd.e\n')
-+ aclf.write('acl allow all publish exchange name=D routingkey=a.*.${domain}\n')
-+ aclf.write('acl allow all publish exchange name=D routingkey=b.#.${domain}\n')
-+ aclf.write('acl allow all publish exchange name=D routingkey=*.${domain}.#.y\n')
-+
-+ # Resolving ${user}_${domain} into ${userdomain} works for everything but routing keys
-+ aclf.write('acl allow all create queue name=mixed-OK-${user}_${domain}\n')
-+ # For routing keys ${user}_${domain} will be parsed into ${userdomain}.
-+ # Routing keys not be found when the rule specifies ${user}_${domain}.
-+ aclf.write('acl allow all publish exchange name=NOGO routingkey=${user}_${domain}.cd.e\n')
-+ # This works since it is does not conflict with ${userdomain}
-+ aclf.write('acl allow all publish exchange name=OK routingkey=${user}___${domain}.cd.e\n')
-+
-+ aclf.write('acl deny-log all all\n')
-+ aclf.close()
-+
-+ result = self.reload_acl()
-+ if (result):
-+ self.fail(result)
-+
-+ self.Lookup("alice@QPID", "create", "queue", "tmp-alice_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "bob_QPID-tmp", {}, "allow")
-+ self.Lookup("charlie@QPID", "create", "queue", "tmp-charlie_QPID-tmp", {}, "allow")
-+ self.Lookup("dave@QPID", "create", "queue", "tmp-dave_QPID-tmp-dave_QPID", {}, "allow")
-+ self.Lookup("ed@BIG.COM", "create", "queue", "tmp-ed_BIG_COM", {}, "allow")
-+ self.Lookup("c.e.r@BIG.GER.COM", "create", "queue", "tmp-c_e_r_BIG_GER_COM", {}, "allow")
-+ self.Lookup("c@", "create", "queue", "tmp-c_", {}, "allow")
-+ self.Lookup("someuser", "create", "queue", "tmp-someuser", {}, "allow")
-+
-+ self.Lookup("alice@QPID", "create", "queue", "tmp-${user}", {}, "deny-log")
-+
-+ self.Lookup("bob@QPID", "create", "exchange", "temp0-bob_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "access", "exchange", "temp0-bob_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "bind", "exchange", "temp0-bob_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "temp0-bob_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "delete", "exchange", "temp0-bob_QPID", {}, "allow")
-+ self.LookupPublish("bob@QPID", "temp0-bob_QPID", "x", "allow")
-+
-+ self.Lookup("bob@QPID", "create", "queue", "temp0-bob_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "access", "queue", "temp0-bob_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "purge", "queue", "temp0-bob_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "consume", "queue", "temp0-bob_QPID", {}, "allow")
-+ self.Lookup("bob@QPID", "delete", "queue", "temp0-bob_QPID", {}, "allow")
-+
-+ self.Lookup("alice@QPID", "access", "queue", "temp0-bob_QPID", {}, "deny-log")
-+
-+ # aclKey: "${userdomain}.cd.e"
-+ self.LookupPublish("uPlain1@COMPANY", "X", "uPlain1_COMPANY.cd.e", "allow")
-+ # aclKey: "a.*.${userdomain}"
-+ self.LookupPublish("uStar1@COMPANY", "X", "a.xx.uStar1_COMPANY", "allow")
-+ self.LookupPublish("uStar1@COMPANY", "X", "a.b", "deny-log")
-+ # aclKey: "b.#.${userdomain}"
-+ self.LookupPublish("uHash1@COMPANY", "X", "b.uHash1_COMPANY", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "X", "b.x.uHash1_COMPANY", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "X", "b..x.y.zz.uHash1_COMPANY", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "X", "b.uHash1_COMPANY.", "deny-log")
-+ self.LookupPublish("uHash1@COMPANY", "X", "q.x.uHash1_COMPANY", "deny-log")
-+ # aclKey: "*.${userdomain}.#.y"
-+ self.LookupPublish("uMixed1@COMPANY", "X", "a.uMixed1_COMPANY.y", "allow")
-+ self.LookupPublish("uMixed1@COMPANY", "X", "a.uMixed1_COMPANY.p.qq.y", "allow")
-+ self.LookupPublish("uMixed1@COMPANY", "X", "a.a.uMixed1_COMPANY.y", "deny-log")
-+ self.LookupPublish("uMixed1@COMPANY", "X", "aa.uMixed1_COMPANY.b.c", "deny-log")
-+ self.LookupPublish("uMixed1@COMPANY.COM", "X", "a.uMixed1_COMPANY_COM.y", "allow")
-+
-+
-+ self.Lookup("bob@QPID", "create", "queue", "user-bob", {}, "allow")
-+ # aclKey: "${user}.cd.e"
-+ self.LookupPublish("uPlain1@COMPANY", "U", "uPlain1.cd.e", "allow")
-+ # aclKey: "a.*.${user}"
-+ self.LookupPublish("uStar1@COMPANY", "U", "a.xx.uStar1", "allow")
-+ self.LookupPublish("uStar1@COMPANY", "U", "a.b", "deny-log")
-+ # aclKey: "b.#.${user}"
-+ self.LookupPublish("uHash1@COMPANY", "U", "b.uHash1", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "U", "b.x.uHash1", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "U", "b..x.y.zz.uHash1", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "U", "b.uHash1.", "deny-log")
-+ self.LookupPublish("uHash1@COMPANY", "U", "q.x.uHash1", "deny-log")
-+ # aclKey: "*.${user}.#.y"
-+ self.LookupPublish("uMixed1@COMPANY", "U", "a.uMixed1.y", "allow")
-+ self.LookupPublish("uMixed1@COMPANY", "U", "a.uMixed1.p.qq.y", "allow")
-+ self.LookupPublish("uMixed1@COMPANY", "U", "a.a.uMixed1.y", "deny-log")
-+ self.LookupPublish("uMixed1@COMPANY", "U", "aa.uMixed1.b.c", "deny-log")
-+ self.LookupPublish("uMixed1@COMPANY.COM", "U", "a.uMixed1.y", "allow")
-+
-+
-+ self.Lookup("bob@QPID", "create", "queue", "domain-QPID", {}, "allow")
-+ # aclKey: "${domain}.cd.e"
-+ self.LookupPublish("uPlain1@COMPANY", "D", "COMPANY.cd.e", "allow")
-+ # aclKey: "a.*.${domain}"
-+ self.LookupPublish("uStar1@COMPANY", "D", "a.xx.COMPANY", "allow")
-+ self.LookupPublish("uStar1@COMPANY", "D", "a.b", "deny-log")
-+ # aclKey: "b.#.${domain}"
-+ self.LookupPublish("uHash1@COMPANY", "D", "b.COMPANY", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "D", "b.x.COMPANY", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "D", "b..x.y.zz.COMPANY", "allow")
-+ self.LookupPublish("uHash1@COMPANY", "D", "b.COMPANY.", "deny-log")
-+ self.LookupPublish("uHash1@COMPANY", "D", "q.x.COMPANY", "deny-log")
-+ # aclKey: "*.${domain}.#.y"
-+ self.LookupPublish("uMixed1@COMPANY", "D", "a.COMPANY.y", "allow")
-+ self.LookupPublish("uMixed1@COMPANY", "D", "a.COMPANY.p.qq.y", "allow")
-+ self.LookupPublish("uMixed1@COMPANY", "D", "a.a.COMPANY.y", "deny-log")
-+ self.LookupPublish("uMixed1@COMPANY", "D", "aa.COMPANY.b.c", "deny-log")
-+ self.LookupPublish("uMixed1@COMPANY.COM", "D", "a.COMPANY_COM.y", "allow")
-+
-+ self.Lookup("uPlain1@COMPANY", "create", "queue", "mixed-OK-uPlain1_COMPANY", {}, "allow")
-+ self.LookupPublish("uPlain1@COMPANY", "NOGO", "uPlain1_COMPANY.cd.e", "deny-log")
-+ self.LookupPublish("uPlain1@COMPANY", "OK", "uPlain1___COMPANY.cd.e", "allow")
-+
-+
-+ #=====================================
-+ # User name substitution details
-+ #=====================================
-+ # User name substitution allows for three flavors of keyword in the Acl file.
-+ # Given a user name of bob.user@QPID.COM the keywords are normalized and resolve as follows:
-+ # ${userdomain} - bob_user_QPID_COM
-+ # ${user} - bob_user
-+ # ${domain} - QPID_COM
-+ #
-+ # The following substitution tests are very similar but differ in the flavor of keyword used
-+ # in the rules. The tests results using the different keywords differ slightly in how permissive
-+ # the rules become.
-+ # ${userdomain} limits access to one authenticated user
-+ # ${user} limits access to a user name regardless of user's domain
-+ # ${domain} limits access to a domain regardless of user name
-+ #
-+
-+ def test_user_name_substitution_userdomain(self):
-+ """
-+ Test a setup where users can create, bind, and publish to a main exchange and queue.
-+ Allow access to a single alternate exchange and queue.
-+ """
-+ aclf = self.get_acl_file()
-+ aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
-+ aclf.write('acl allow-log anonymous create queue\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qmf.*\n')
-+ aclf.write('acl allow-log anonymous all exchange name=amq.direct\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qpid.management\n')
-+ aclf.write('acl allow-log anonymous access method name=*\n')
-+ aclf.write('# end hack alert\n')
-+ # Create primary queue and exchange:
-+ # allow predefined alternate
-+ # deny any other alternate
-+ # allow no alternate
-+ aclf.write('acl allow all create queue name=${userdomain}-work alternate=${userdomain}-work2\n')
-+ aclf.write('acl deny all create queue name=${userdomain}-work alternate=*\n')
-+ aclf.write('acl allow all create queue name=${userdomain}-work\n')
-+ aclf.write('acl allow all create exchange name=${userdomain}-work alternate=${userdomain}-work2\n')
-+ aclf.write('acl deny all create exchange name=${userdomain}-work alternate=*\n')
-+ aclf.write('acl allow all create exchange name=${userdomain}-work\n')
-+ # Create backup queue and exchange
-+ # Deny any alternate
-+ aclf.write('acl deny all create queue name=${userdomain}-work2 alternate=*\n')
-+ aclf.write('acl allow all create queue name=${userdomain}-work2\n')
-+ aclf.write('acl deny all create exchange name=${userdomain}-work2 alternate=*\n')
-+ aclf.write('acl allow all create exchange name=${userdomain}-work2\n')
-+ # Bind/unbind primary exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all bind exchange name=${userdomain}-work routingkey=${userdomain} queuename=${userdomain}-work\n')
-+ aclf.write('acl allow all unbind exchange name=${userdomain}-work routingkey=${userdomain} queuename=${userdomain}-work\n')
-+ # Bind/unbind backup exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all bind exchange name=${userdomain}-work2 routingkey=${userdomain} queuename=${userdomain}-work2\n')
-+ aclf.write('acl allow all unbind exchange name=${userdomain}-work2 routingkey=${userdomain} queuename=${userdomain}-work2\n')
-+ # Access primary exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all access exchange name=${userdomain}-work routingkey=${userdomain} queuename=${userdomain}-work\n')
-+ # Access backup exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all access exchange name=${userdomain}-work2 routingkey=${userdomain} queuename=${userdomain}-work2\n')
-+ # Publish primary exchange
-+ # Use only predefined routingkey
-+ aclf.write('acl allow all publish exchange name=${userdomain}-work routingkey=${userdomain}\n')
-+ # Publish backup exchange
-+ # Use only predefined routingkey
-+ aclf.write('acl allow all publish exchange name=${userdomain}-work2 routingkey=${userdomain}\n')
-+ # deny mode
-+ aclf.write('acl deny all all\n')
-+ aclf.close()
-+
-+ result = self.reload_acl()
-+ if (result):
-+ self.fail(result)
-+
-+ # create queues
-+ self.Lookup("bob@QPID", "create", "queue", "bob_QPID-work", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "bob_QPID-work2", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "joe_QPID-work", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "joe_QPID-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "bob_QPID-work3", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "bob_QPID-work", {"alternate":"bob_QPID-work2"}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "bob_QPID-work", {"alternate":"joe_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "bob_QPID-work2", {"alternate":"someexchange"}, "deny")
-+ # create exchanges
-+ self.Lookup("bob@QPID", "create", "exchange", "bob_QPID-work", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "bob_QPID-work2",{}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "joe_QPID-work", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "exchange", "joe_QPID-work2",{}, "deny")
-+ self.Lookup("bob@QPID", "create", "exchange", "bob_QPID-work3",{}, "deny")
-+ self.Lookup("bob@QPID", "create", "exchange", "bob_QPID-work", {"alternate":"bob_QPID-work2"}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "bob_QPID-work2",{"alternate":"someexchange"}, "deny")
-+ # bind/unbind/access
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", { "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "allow")
-+ self.Lookup("bob@QPID", "bind", "exchange", "joe_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work"}, "deny")
-+
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", { "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "allow")
-+ self.Lookup("bob@QPID", "bind", "exchange", "joe_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work2"}, "deny")
-+
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", { "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "allow")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "joe_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work"}, "deny")
-+
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", { "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "allow")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "joe_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work2"}, "deny")
-+
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", { "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "allow")
-+ self.Lookup("bob@QPID", "access", "exchange", "joe_QPID-work", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work"}, "deny")
-+
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", { "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "allow")
-+ self.Lookup("bob@QPID", "access", "exchange", "joe_QPID-work2", {"routingkey":"bob_QPID", "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {"routingkey":"joe_QPID", "queuename":"bob_QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob_QPID-work2", {"routingkey":"bob_QPID", "queuename":"joe_QPID-work2"}, "deny")
-+ # publish
-+ self.LookupPublish("bob@QPID", "bob_QPID-work", "bob_QPID", "allow")
-+ self.LookupPublish("bob@QPID", "bob_QPID-work2", "bob_QPID", "allow")
-+ self.LookupPublish("bob@QPID", "joe_QPID-work", "bob_QPID", "deny")
-+ self.LookupPublish("bob@QPID", "joe_QPID-work2", "bob_QPID", "deny")
-+ self.LookupPublish("bob@QPID", "bob_QPID-work", "joe_QPID", "deny")
-+ self.LookupPublish("bob@QPID", "bob_QPID-work2", "joe_QPID", "deny")
-+
-+
-+ def test_user_name_substitution_user(self):
-+ """
-+ Test a setup where users can create, bind, and publish to a main exchange and queue.
-+ Allow access to a single backup exchange and queue.
-+ """
-+ aclf = self.get_acl_file()
-+ aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
-+ aclf.write('acl allow-log anonymous create queue\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qmf.*\n')
-+ aclf.write('acl allow-log anonymous all exchange name=amq.direct\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qpid.management\n')
-+ aclf.write('acl allow-log anonymous access method name=*\n')
-+ aclf.write('# end hack alert\n')
-+ # Create primary queue and exchange
-+ # allow predefined alternate
-+ # deny any other alternate
-+ # allow no alternate
-+ aclf.write('acl allow all create queue name=${user}-work alternate=${user}-work2\n')
-+ aclf.write('acl deny all create queue name=${user}-work alternate=*\n')
-+ aclf.write('acl allow all create queue name=${user}-work\n')
-+ aclf.write('acl allow all create exchange name=${user}-work alternate=${user}-work2\n')
-+ aclf.write('acl deny all create exchange name=${user}-work alternate=*\n')
-+ aclf.write('acl allow all create exchange name=${user}-work\n')
-+ # Create backup queue and exchange
-+ # Deny any alternate
-+ aclf.write('acl deny all create queue name=${user}-work2 alternate=*\n')
-+ aclf.write('acl allow all create queue name=${user}-work2\n')
-+ aclf.write('acl deny all create exchange name=${user}-work2 alternate=*\n')
-+ aclf.write('acl allow all create exchange name=${user}-work2\n')
-+ # Bind/unbind primary exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all bind exchange name=${user}-work routingkey=${user} queuename=${user}-work\n')
-+ aclf.write('acl allow all unbind exchange name=${user}-work routingkey=${user} queuename=${user}-work\n')
-+ # Bind/unbind backup exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all bind exchange name=${user}-work2 routingkey=${user} queuename=${user}-work2\n')
-+ aclf.write('acl allow all unbind exchange name=${user}-work2 routingkey=${user} queuename=${user}-work2\n')
-+ # Access primary exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all access exchange name=${user}-work routingkey=${user} queuename=${user}-work\n')
-+ # Access backup exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all access exchange name=${user}-work2 routingkey=${user} queuename=${user}-work2\n')
-+ # Publish primary exchange
-+ # Use only predefined routingkey
-+ aclf.write('acl allow all publish exchange name=${user}-work routingkey=${user}\n')
-+ # Publish backup exchange
-+ # Use only predefined routingkey
-+ aclf.write('acl allow all publish exchange name=${user}-work2 routingkey=${user}\n')
-+ # deny mode
-+ aclf.write('acl deny all all\n')
-+ aclf.close()
-+
-+ result = self.reload_acl()
-+ if (result):
-+ self.fail(result)
-+
-+ # create queues
-+ self.Lookup("bob@QPID", "create", "queue", "bob-work", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "bob-work2", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "joe-work", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "joe-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "bob-work3", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "bob-work", {"alternate":"bob-work2"}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "bob-work", {"alternate":"joe-work2"}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "bob-work2", {"alternate":"someexchange"},"deny")
-+ # create exchanges
-+ self.Lookup("bob@QPID", "create", "exchange", "bob-work", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "bob-work2",{}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "joe-work", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "exchange", "joe-work2",{}, "deny")
-+ self.Lookup("bob@QPID", "create", "exchange", "bob-work3",{}, "deny")
-+ self.Lookup("bob@QPID", "create", "exchange", "bob-work", {"alternate":"bob-work2"}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "bob-work2",{"alternate":"someexchange"},"deny")
-+ # bind/unbind/access
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {"routingkey":"bob"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work", { "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {"routingkey":"bob", "queuename":"bob-work"}, "allow")
-+ self.Lookup("bob@QPID", "bind", "exchange", "joe-work", {"routingkey":"bob", "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {"routingkey":"joe", "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work", {"routingkey":"bob", "queuename":"joe-work"}, "deny")
-+
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {"routingkey":"bob"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", { "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "allow")
-+ self.Lookup("bob@QPID", "bind", "exchange", "joe-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {"routingkey":"joe", "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"joe-work2"}, "deny")
-+
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {"routingkey":"bob"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", { "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {"routingkey":"bob", "queuename":"bob-work"}, "allow")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "joe-work", {"routingkey":"bob", "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {"routingkey":"joe", "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work", {"routingkey":"bob", "queuename":"joe-work"}, "deny")
-+
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {"routingkey":"bob"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", { "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "allow")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "joe-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {"routingkey":"joe", "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"joe-work2"}, "deny")
-+
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work", {}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work", {"routingkey":"bob"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work", { "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work", {"routingkey":"bob", "queuename":"bob-work"}, "allow")
-+ self.Lookup("bob@QPID", "access", "exchange", "joe-work", {"routingkey":"bob", "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work", {"routingkey":"joe", "queuename":"bob-work"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work", {"routingkey":"bob", "queuename":"joe-work"}, "deny")
-+
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {"routingkey":"bob"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work2", { "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "allow")
-+ self.Lookup("bob@QPID", "access", "exchange", "joe-work2", {"routingkey":"bob", "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {"routingkey":"joe", "queuename":"bob-work2"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "bob-work2", {"routingkey":"bob", "queuename":"joe-work2"}, "deny")
-+ # publish
-+ self.LookupPublish("bob@QPID", "bob-work", "bob", "allow")
-+ self.LookupPublish("bob@QPID", "bob-work2", "bob", "allow")
-+ self.LookupPublish("bob@QPID", "joe-work", "bob", "deny")
-+ self.LookupPublish("bob@QPID", "joe-work2", "bob", "deny")
-+ self.LookupPublish("bob@QPID", "bob-work", "joe", "deny")
-+ self.LookupPublish("bob@QPID", "bob-work2", "joe", "deny")
-+
-+
-+ def test_user_name_substitution_domain(self):
-+ """
-+ Test a setup where users can create, bind, and publish to a main exchange and queue.
-+ Allow access to a single backup exchange and queue.
-+ """
-+ aclf = self.get_acl_file()
-+ aclf.write('# begin hack alert: allow anonymous to access the lookup debug functions\n')
-+ aclf.write('acl allow-log anonymous create queue\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qmf.*\n')
-+ aclf.write('acl allow-log anonymous all exchange name=amq.direct\n')
-+ aclf.write('acl allow-log anonymous all exchange name=qpid.management\n')
-+ aclf.write('acl allow-log anonymous access method name=*\n')
-+ aclf.write('# end hack alert\n')
-+ # Create primary queue and exchange
-+ # allow predefined alternate
-+ # deny any other alternate
-+ # allow no alternate
-+ aclf.write('acl allow all create queue name=${domain}-work alternate=${domain}-work2\n')
-+ aclf.write('acl deny all create queue name=${domain}-work alternate=*\n')
-+ aclf.write('acl allow all create queue name=${domain}-work\n')
-+ aclf.write('acl allow all create exchange name=${domain}-work alternate=${domain}-work2\n')
-+ aclf.write('acl deny all create exchange name=${domain}-work alternate=*\n')
-+ aclf.write('acl allow all create exchange name=${domain}-work\n')
-+ # Create backup queue and exchange
-+ # Deny any alternate
-+ aclf.write('acl deny all create queue name=${domain}-work2 alternate=*\n')
-+ aclf.write('acl allow all create queue name=${domain}-work2\n')
-+ aclf.write('acl deny all create exchange name=${domain}-work2 alternate=*\n')
-+ aclf.write('acl allow all create exchange name=${domain}-work2\n')
-+ # Bind/unbind primary exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all bind exchange name=${domain}-work routingkey=${domain} queuename=${domain}-work\n')
-+ aclf.write('acl allow all unbind exchange name=${domain}-work routingkey=${domain} queuename=${domain}-work\n')
-+ # Bind/unbind backup exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all bind exchange name=${domain}-work2 routingkey=${domain} queuename=${domain}-work2\n')
-+ aclf.write('acl allow all unbind exchange name=${domain}-work2 routingkey=${domain} queuename=${domain}-work2\n')
-+ # Access primary exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all access exchange name=${domain}-work routingkey=${domain} queuename=${domain}-work\n')
-+ # Access backup exchange
-+ # Use only predefined routingkey and queuename
-+ aclf.write('acl allow all access exchange name=${domain}-work2 routingkey=${domain} queuename=${domain}-work2\n')
-+ # Publish primary exchange
-+ # Use only predefined routingkey
-+ aclf.write('acl allow all publish exchange name=${domain}-work routingkey=${domain}\n')
-+ # Publish backup exchange
-+ # Use only predefined routingkey
-+ aclf.write('acl allow all publish exchange name=${domain}-work2 routingkey=${domain}\n')
-+ # deny mode
-+ aclf.write('acl deny all all\n')
-+ aclf.close()
-+
-+ result = self.reload_acl()
-+ if (result):
-+ self.fail(result)
-+
-+ # create queues
-+ self.Lookup("bob@QPID", "create", "queue", "QPID-work", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "QPID-work2", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "QPID-work3", {}, "deny")
-+ self.Lookup("bob@QPID", "create", "queue", "QPID-work", {"alternate":"QPID-work2"}, "allow")
-+ self.Lookup("bob@QPID", "create", "queue", "QPID-work", {"alternate":"bob_QPID-work2"},"deny")
-+ self.Lookup("bob@QPID", "create", "queue", "QPID-work", {"alternate":"joe_QPID-work2"},"deny")
-+ self.Lookup("bob@QPID", "create", "queue", "QPID-work2", {"alternate":"someexchange"}, "deny")
-+ # create exchanges
-+ self.Lookup("bob@QPID", "create", "exchange", "QPID-work", {}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "QPID-work2",{}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "QPID-work3",{}, "deny")
-+ self.Lookup("bob@QPID", "create", "exchange", "QPID-work", {"alternate":"QPID-work2"}, "allow")
-+ self.Lookup("bob@QPID", "create", "exchange", "QPID-work2",{"alternate":"someexchange"}, "deny")
-+ # bind/unbind/access
-+ self.Lookup("bob@QPID", "bind", "exchange", "QPID-work", {}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "QPID-work", {"routingkey":"QPID"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "QPID-work", { "queuename":"QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "QPID-work", {"routingkey":"QPID", "queuename":"QPID-work"}, "allow")
-+
-+ self.Lookup("bob@QPID", "bind", "exchange", "QPID-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "QPID-work2", {"routingkey":"QPID"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "QPID-work2", { "queuename":"QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "bind", "exchange", "QPID-work2", {"routingkey":"QPID", "queuename":"QPID-work2"}, "allow")
-+
-+ self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work", {}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work", {"routingkey":"QPID"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work", { "queuename":"QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work", {"routingkey":"QPID", "queuename":"QPID-work"}, "allow")
-+
-+ self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work2", {"routingkey":"QPID"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work2", { "queuename":"QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "unbind", "exchange", "QPID-work2", {"routingkey":"QPID", "queuename":"QPID-work2"}, "allow")
-+
-+ self.Lookup("bob@QPID", "access", "exchange", "QPID-work", {}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "QPID-work", {"routingkey":"QPID"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "QPID-work", { "queuename":"QPID-work"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "QPID-work", {"routingkey":"QPID", "queuename":"QPID-work"}, "allow")
-+
-+ self.Lookup("bob@QPID", "access", "exchange", "QPID-work2", {}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "QPID-work2", {"routingkey":"QPID"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "QPID-work2", { "queuename":"QPID-work2"}, "deny")
-+ self.Lookup("bob@QPID", "access", "exchange", "QPID-work2", {"routingkey":"QPID", "queuename":"QPID-work2"}, "allow")
-+ # publish
-+ self.LookupPublish("bob@QPID", "QPID-work", "QPID", "allow")
-+ self.LookupPublish("bob@QPID", "QPID-work2", "QPID", "allow")
-+ self.LookupPublish("joe@QPID", "QPID-work", "QPID", "allow")
-+ self.LookupPublish("joe@QPID", "QPID-work2", "QPID", "allow")
-+
-+
- class BrokerAdmin:
- def __init__(self, broker, username=None, password=None):
- self.connection = qpid.messaging.Connection(broker)
---
-1.7.1
-
-From dccba01e71e738e0e3789e062c712da7e6b9e7b3 Mon Sep 17 00:00:00 2001
-From: Charles E. Rolke
-Date: Tue, 21 Aug 2012 14:42:51 +0000
-Subject: [PATCH 10/19] QPID-4230 Username substitution keywords in Acl file. Repair function definitions that fail Windows compile.
-
-git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1375583 13f79535-47bb-0310-9956-ffa450edef68
----
- qpid/cpp/src/qpid/acl/AclData.cpp | 8 ++++----
- 1 files changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/qpid/cpp/src/qpid/acl/AclData.cpp b/qpid/cpp/src/qpid/acl/AclData.cpp
-index 7c14d09..6994de2 100644
---- a/qpid/cpp/src/qpid/acl/AclData.cpp
-+++ b/qpid/cpp/src/qpid/acl/AclData.cpp
-@@ -607,8 +607,8 @@ namespace acl {
- // Given an Acl rule and an authenticated userId
- // do the keyword substitutions on the rule.
- //
-- void AclData::AclData::substituteUserId(std::string& ruleString,
-- const std::string& userId)
-+ void AclData::substituteUserId(std::string& ruleString,
-+ const std::string& userId)
- {
- size_t locDomSeparator(0);
- std::string user("");
-@@ -640,8 +640,8 @@ namespace acl {
- // topic key lookups where the keyword string proper is in the
- // topic key search tree.
- //
-- void AclData::AclData::substituteKeywords(std::string& ruleString,
-- const std::string& userId)
-+ void AclData::substituteKeywords(std::string& ruleString,
-+ const std::string& userId)
- {
- size_t locDomSeparator(0);
- std::string user("");
---
-1.7.1
-
-From 9133f1e58739093af5cdad674e0f2ee30c10188d Mon Sep 17 00:00:00 2001
-From: Chuck Rolke
-Date: Mon, 20 Aug 2012 15:44:34 -0400
-Subject: [PATCH 11/19] This sort of works. It needs some refactoring.
-
----
- qpid/cpp/src/qpid/acl/Acl.cpp | 14 +++-
- qpid/cpp/src/qpid/acl/Acl.h | 5 +-
- qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp | 116 +++++++++++++++++++++---
- qpid/cpp/src/qpid/acl/AclConnectionCounter.h | 35 ++++++--
- qpid/cpp/src/qpid/acl/AclPlugin.cpp | 1 +
- qpid/cpp/src/qpid/broker/AclModule.h | 5 +
- qpid/cpp/src/qpid/broker/Broker.cpp | 5 +
- qpid/cpp/src/tests/acl.py | 50 ++++++++++
- qpid/cpp/src/tests/run_acl_tests | 16 +++-
- 9 files changed, 220 insertions(+), 27 deletions(-)
-
-diff --git a/qpid/cpp/src/qpid/acl/Acl.cpp b/qpid/cpp/src/qpid/acl/Acl.cpp
-index 89c4b34..8116e67 100644
---- a/qpid/cpp/src/qpid/acl/Acl.cpp
-+++ b/qpid/cpp/src/qpid/acl/Acl.cpp
-@@ -51,7 +51,7 @@ using qpid::management::Args;
- namespace _qmf = qmf::org::apache::qpid::acl;
-
- Acl::Acl (AclValues& av, Broker& b): aclValues(av), broker(&b), transferAcl(false), mgmtObject(0),
-- connectionCounter(new ConnectionCounter(*this, aclValues.aclMaxConnectPerUser, aclValues.aclMaxConnectPerIp, aclValues.aclMaxConnectTotal))
-+ connectionCounter(new ConnectionCounter(*this, aclValues.aclMaxConnectPerUser, aclValues.aclMaxConnectPerIp, aclValues.aclMaxConnectTotal, aclValues.aclMaxQueuesPerUser))
- {
-
- agent = broker->getManagementAgent();
-@@ -136,6 +136,18 @@ void Acl::setUserId(const qpid::broker::Connection& connection, const std::strin
- }
-
-
-+bool Acl::approveCreateQueue(const std::string& userId, const std::string& queueName)
-+{
-+ return connectionCounter->approveCreateQueue(userId, queueName);
-+}
-+
-+
-+void Acl::recordDestroyQueue(const std::string& queueName)
-+{
-+ connectionCounter->recordDestroyQueue(queueName);
-+}
-+
-+
- bool Acl::result(
- const AclResult& aclreslt,
- const std::string& id,
-diff --git a/qpid/cpp/src/qpid/acl/Acl.h b/qpid/cpp/src/qpid/acl/Acl.h
-index 4787934..918b98c 100644
---- a/qpid/cpp/src/qpid/acl/Acl.h
-+++ b/qpid/cpp/src/qpid/acl/Acl.h
-@@ -49,6 +49,7 @@ struct AclValues {
- uint16_t aclMaxConnectPerUser;
- uint16_t aclMaxConnectPerIp;
- uint16_t aclMaxConnectTotal;
-+ uint16_t aclMaxQueuesPerUser;
- };
-
-
-@@ -92,9 +93,11 @@ public:
- const std::string& ExchangeName,
- const std::string& RoutingKey);
-
-+ // Resource quota tracking
- virtual bool approveConnection(const broker::Connection& connection);
--
- virtual void setUserId(const broker::Connection& connection, const std::string& username);
-+ virtual bool approveCreateQueue(const std::string& userId, const std::string& queueName);
-+ virtual void recordDestroyQueue(const std::string& queueName);
-
- virtual ~Acl();
- private:
-diff --git a/qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp b/qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp
-index 8c6e3ee..56dbced 100644
---- a/qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp
-+++ b/qpid/cpp/src/qpid/acl/AclConnectionCounter.cpp
-@@ -42,8 +42,10 @@ namespace acl {
- //
- //
- //
--ConnectionCounter::ConnectionCounter(Acl& a, uint16_t nl, uint16_t hl, uint16_t tl) :
-- acl(a), nameLimit(nl), hostLimit(hl), totalLimit(tl), totalCurrentConnections(0) {}
-+ConnectionCounter::ConnectionCounter(Acl& a, uint16_t nl, uint16_t hl, uint16_t tl, uint16_t ql) :
-+ acl(a), nameLimit(nl), hostLimit(hl), totalLimit(tl), queueLimit(ql), totalCurrentConnections(0) {
-+ QPID_LOG(critical, "ACL CONNECTION_COUNTER nameLimit:" << nameLimit << ", hostLimit:" << hostLimit << ", totalLimit:" << totalLimit << ", queueLimit:" << queueLimit);
-+ }
-
- ConnectionCounter::~ConnectionCounter() {}
-
-@@ -55,7 +57,7 @@ ConnectionCounter::~ConnectionCounter() {}
- // Called with lock held.
- //
- bool ConnectionCounter::limitApproveLH(
-- connectCountsMap_t& theMap,
-+ countsMap_t& theMap,
- const std::string& theName,
- uint16_t theLimit,
- bool emitLog) {
-@@ -63,7 +65,7 @@ bool ConnectionCounter::limitApproveLH(
- bool result(true);
- if (theLimit > 0) {
- uint16_t count;
-- connectCountsMap_t::iterator eRef = theMap.find(theName);
-+ countsMap_t::iterator eRef = theMap.find(theName);
- if (eRef != theMap.end()) {
- count = (uint16_t)(*eRef).second;
- result = count <= theLimit;
-@@ -73,9 +75,49 @@ bool ConnectionCounter::limitApproveLH(
- }
- if (emitLog) {
- QPID_LOG(trace, "ACL ConnectionApprover IP=" << theName
-- << " limit=" << theLimit
-- << " curValue=" << count
-- << " result=" << (result ? "allow" : "deny"));
-+ << " limit=" << theLimit
-+ << " curValue=" << count
-+ << " result=" << (result ? "allow" : "deny"));
-+ }
-+ }
-+ return result;
-+}
-+
-+
-+//
-+// limitApproveLH
-+//
-+// Resource creation approver.
-+// If user is under limit increment count and return true.
-+// Called with lock held.
-+//
-+bool ConnectionCounter::limitApproveLH(
-+ const std::string& theTitle,
-+ countsMap_t& theMap,
-+ const std::string& theName,
-+ uint16_t theLimit,
-+ bool emitLog) {
-+
-+ bool result(true);
-+ if (theLimit > 0) {
-+ uint16_t count;
-+ countsMap_t::iterator eRef = theMap.find(theName);
-+ if (eRef != theMap.end()) {
-+ count = (uint16_t)(*eRef).second;
-+ result = count < theLimit;
-+ if (result) {
-+ count += 1;
-+ (*eRef).second = count;
-+ }
-+ } else {
-+ // Not found
-+ theMap[theName] = count = 1;
-+ }
-+ if (emitLog) {
-+ QPID_LOG(trace, theTitle << theName
-+ << " limit=" << theLimit
-+ << " curValue=" << count
-+ << " result=" << (result ? "allow" : "deny"));
- }
- }
- return result;
-@@ -89,7 +131,7 @@ bool ConnectionCounter::limitApproveLH(
- // called with dataLock already taken
- //
- bool ConnectionCounter::countConnectionLH(
-- connectCountsMap_t& theMap,
-+ countsMap_t& theMap,
- const std::string& theName,
- uint16_t theLimit,
- bool emitLog) {
-@@ -97,7 +139,7 @@ bool ConnectionCounter::countConnectionLH(
- bool result(true);
- uint16_t count(0);
- if (theLimit > 0) {
-- connectCountsMap_t::iterator eRef = theMap.find(theName);
-+ countsMap_t::iterator eRef = theMap.find(theName);
- if (eRef != theMap.end()) {
- count = (uint16_t)(*eRef).second + 1;
- (*eRef).second = count;
-@@ -123,10 +165,10 @@ bool ConnectionCounter::countConnectionLH(
- // called with dataLock already taken
- //
- void ConnectionCounter::releaseLH(
-- connectCountsMap_t& theMap, const std::string& theName, uint16_t theLimit) {
-+ countsMap_t& theMap, const std::string& theName, uint16_t theLimit) {
-
- if (theLimit > 0) {
-- connectCountsMap_t::iterator eRef = theMap.find(theName);
-+ countsMap_t::iterator eRef = theMap.find(theName);
- if (eRef != theMap.end()) {
- uint16_t count = (uint16_t) (*eRef).second;
- assert (count > 0);
-@@ -174,7 +216,7 @@ void ConnectionCounter::closed(broker::Connection& connection) {
-
- Mutex::ScopedLock locker(dataLock);
-
-- connectCountsMap_t::iterator eRef = connectProgressMap.find(connection.getMgmtId());
-+ countsMap_t::iterator eRef = connectProgressMap.find(connection.getMgmtId());
- if (eRef != connectProgressMap.end()) {
- if ((*eRef).second == C_OPENED){
- // Normal case: connection was created and opened.
-@@ -306,7 +348,7 @@ void ConnectionCounter::setUserId(const broker::Connection& connection,
- {
- Mutex::ScopedLock locker(dataLock);
-
-- connectCountsMap_t::iterator eRef = connectProgressMap.find(connection.getMgmtId());
-+ countsMap_t::iterator eRef = connectProgressMap.find(connection.getMgmtId());
- if (eRef != connectProgressMap.end()) {
- if ((*eRef).second == C_OPENED){
- // Connection has been opened so that current user has been counted
-@@ -338,6 +380,54 @@ void ConnectionCounter::setUserId(const broker::Connection& connection,
-
-
- //
-+// approveCreateQueue
-+// Count an attempted queue creation by this user.
-+// Disapprove if over limit.
-+//
-+bool ConnectionCounter::approveCreateQueue(const std::string& userId, const std::string& queueName)
-+{
-+ Mutex::ScopedLock locker(dataLock);
-+
-+ QPID_LOG(critical, "approveCreateQueue ----------- userId:" << userId << ", queueName:" << queueName);
-+
-+ bool okByQ = limitApproveLH("ACL Queue creation approver. userId:", queuePerUserMap, userId, queueLimit, true);
-+
-+ if (okByQ) {
-+ // Queue is owned by this userId
-+ queueOwnerMap[queueName] = userId;
-+
-+ QPID_LOG(trace, "ACL create queue approved for user '" << userId
-+ << "' queue '" << queueName << "'");
-+ } else {
-+
-+ QPID_LOG(error, "Client max queue count limit of " << queueLimit
-+ << " exceeded by '" << userId << "' creating queue '"
-+ << queueName << "'. Queue creation denied.");
-+ }
-+ return okByQ;
-+}
-+
-+
-+//
-+// recordDestroyQueue
-+// Return a destroyed queue to a user's quota
-+//
-+void ConnectionCounter::recordDestroyQueue(const std::string& queueName)
-+{
-+ Mutex::ScopedLock locker(dataLock);
-+
-+ queueOwnerMap_t::iterator eRef = queueOwnerMap.find(queueName);
-+ if (eRef != queueOwnerMap.end()) {
-+ releaseLH(queuePerUserMap, (*eRef).second, queueLimit);
-+
-+ queueOwnerMap.erase(eRef);
-+ } else {
-+ QPID_LOG(notice, "ACL owner for queue '" << queueName
-+ << "' not found in owner map");
-+ }
-+}
-+
-+//
- // getClientIp - given a connection's mgmtId return the client host part.
- //
- // TODO: Ideally this would be a method of the connection itself.
-diff --git a/qpid/cpp/src/qpid/acl/AclConnectionCounter.h b/qpid/cpp/src/qpid/acl/AclConnectionCounter.h
-index 54fa693..70c60fb 100644
---- a/qpid/cpp/src/qpid/acl/AclConnectionCounter.h
-+++ b/qpid/cpp/src/qpid/acl/AclConnectionCounter.h
-@@ -44,48 +44,63 @@ class Acl;
- class ConnectionCounter : public broker::ConnectionObserver
- {
- private:
-- typedef std::map connectCountsMap_t;
-+ typedef std::map countsMap_t;
- enum CONNECTION_PROGRESS { C_CREATED=1, C_OPENED=2 };
-+ typedef std::map queueOwnerMap_t;
-
- Acl& acl;
- uint16_t nameLimit;
- uint16_t hostLimit;
- uint16_t totalLimit;
-+ uint16_t queueLimit;
- uint16_t totalCurrentConnections;
- qpid::sys::Mutex dataLock;
-
- /** Records per-connection state */
-- connectCountsMap_t connectProgressMap;
-+ countsMap_t connectProgressMap;
-
- /** Records per-username counts */
-- connectCountsMap_t connectByNameMap;
-+ countsMap_t connectByNameMap;
-
- /** Records per-host counts */
-- connectCountsMap_t connectByHostMap;
-+ countsMap_t connectByHostMap;
-+
-+ /** Records queueName-queueUserId */
-+ queueOwnerMap_t queueOwnerMap;
-+
-+ /** Records queue-by-owner counts */
-+ countsMap_t queuePerUserMap;
-
- /** Given a connection's management ID, return the client host name */
- std::string getClientHost(const std::string mgmtId);
-
- /** Return approval for proposed connection */
-- bool limitApproveLH(connectCountsMap_t& theMap,
-+ bool limitApproveLH(countsMap_t& theMap,
-+ const std::string& theName,
-+ uint16_t theLimit,
-+ bool emitLog);
-+
-+ /** Return approval for proposed resource creation */
-+ bool limitApproveLH(const std::string& theTitle,
-+ countsMap_t& theMap,
- const std::string& theName,
- uint16_t theLimit,
- bool emitLog);
-
- /** Record a connection.
- * @return indication if user/host is over its limit */
-- bool countConnectionLH(connectCountsMap_t& theMap,
-+ bool countConnectionLH(countsMap_t& theMap,
- const std::string& theName,
- uint16_t theLimit,
- bool emitLog);
-
- /** Release a connection */
-- void releaseLH(connectCountsMap_t& theMap,
-+ void releaseLH(countsMap_t& theMap,
- const std::string& theName,
- uint16_t theLimit);
-
- public:
-- ConnectionCounter(Acl& acl, uint16_t nl, uint16_t hl, uint16_t tl);
-+ ConnectionCounter(Acl& acl, uint16_t nl, uint16_t hl, uint16_t tl, uint16_t ql);
- ~ConnectionCounter();
-
- // ConnectionObserver interface
-@@ -95,6 +110,10 @@ public:
- // Connection counting
- bool approveConnection(const broker::Connection& conn);
- void setUserId(const broker::Connection& connection, const std::string& username);
-+
-+ // Queue counting
-+ bool approveCreateQueue(const std::string& userId, const std::string& queueName);
-+ void recordDestroyQueue(const std::string& queueName);
- };
-
- }} // namespace qpid::ha
-diff --git a/qpid/cpp/src/qpid/acl/AclPlugin.cpp b/qpid/cpp/src/qpid/acl/AclPlugin.cpp
-index ebf5e90..4aaa00a 100644
---- a/qpid/cpp/src/qpid/acl/AclPlugin.cpp
-+++ b/qpid/cpp/src/qpid/acl/AclPlugin.cpp
-@@ -45,6 +45,7 @@ struct AclOptions : public Options {
- ("max-connections" , optValue(values.aclMaxConnectTotal, "N"), "The maximum combined number of connections allowed. 0 implies no limit.")
- ("max-connections-per-user", optValue(values.aclMaxConnectPerUser, "N"), "The maximum number of connections allowed per user. 0 implies no limit.")
- ("max-connections-per-ip" , optValue(values.aclMaxConnectPerIp, "N"), "The maximum number of connections allowed per host IP address. 0 implies no limit.")
-+ ("max-queues-per-user", optValue(values.aclMaxQueuesPerUser, "N"), "The maximum number of queues allowed per user. 0 implies no limit.")
- ;
- }
- };
-diff --git a/qpid/cpp/src/qpid/broker/AclModule.h b/qpid/cpp/src/qpid/broker/AclModule.h
-index 4caf8ed..987d3e4 100644
---- a/qpid/cpp/src/qpid/broker/AclModule.h
-+++ b/qpid/cpp/src/qpid/broker/AclModule.h
-@@ -151,6 +151,11 @@ namespace broker {
- */
- virtual void setUserId(const Connection& connection, const std::string& username)=0;
-
-+ /** Approve queue creation by counting per-user.
-+ */
-+ virtual bool approveCreateQueue(const std::string& userId, const std::string& queueName)=0;
-+ virtual void recordDestroyQueue(const std::string& queueName)=0;
-+
- virtual ~AclModule() {};
- };
- } // namespace broker
-diff --git a/qpid/cpp/src/qpid/broker/Broker.cpp b/qpid/cpp/src/qpid/broker/Broker.cpp
-index c202d9c..be7340a 100644
---- a/qpid/cpp/src/qpid/broker/Broker.cpp
-+++ b/qpid/cpp/src/qpid/broker/Broker.cpp
-@@ -1076,6 +1076,9 @@ std::pair, bool> Broker::createQueue(
-
- if (!acl->authorise(userId,acl::ACT_CREATE,acl::OBJ_QUEUE,name,¶ms) )
- throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue create request from " << userId));
-+
-+ if (!acl->approveCreateQueue(userId,name) )
-+ throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue create request from " << userId));
- }
-
- Exchange::shared_ptr alternate;
-@@ -1113,6 +1116,8 @@ void Broker::deleteQueue(const std::string& name, const std::string& userId,
- Queue::shared_ptr queue = queues.find(name);
- if (queue) {
- if (check) check(queue);
-+ if (acl)
-+ acl->recordDestroyQueue(name);
- queues.destroy(name);
- queue->destroyed();
- } else {
-diff --git a/qpid/cpp/src/tests/acl.py b/qpid/cpp/src/tests/acl.py
-index 102796c..8055996 100755
---- a/qpid/cpp/src/tests/acl.py
-+++ b/qpid/cpp/src/tests/acl.py
-@@ -53,6 +53,9 @@ class ACLTests(TestBase010):
- def port_u(self):
- return int(self.defines["port-u"])
-
-+ def port_q(self):
-+ return int(self.defines["port-q"])
-+
- def get_session_by_port(self, user, passwd, byPort):
- socket = connect(self.broker.host, byPort)
- connection = Connection (sock=socket, username=user, password=passwd,
-@@ -2243,6 +2246,53 @@ class ACLTests(TestBase010):
- self.LookupPublish("joe@QPID", "QPID-work", "QPID", "allow")
- self.LookupPublish("joe@QPID", "QPID-work2", "QPID", "allow")
-
-+ #=====================================
-+ # Queue limits
-+ #=====================================
-+
-+ def test__queue_limits(self):
-+ """
-+ Test ACL control queue limits
-+ """
-+ # bob should be able to create two queues
-+ session = self.get_session_by_port('bob','bob', self.port_q())
-+
-+ try:
-+ session.queue_declare(queue="queue1")
-+ session.queue_declare(queue="queue2")
-+ except qpid.session.SessionException, e:
-+ self.fail("Error during queue create request");
-+
-+ # third queue should fail
-+ try:
-+ session.queue_declare(queue="queue3")
-+ self.fail("Should not be able to create third queue")
-+ except Exception, e:
-+ result = None
-+ session = self.get_session_by_port('bob','bob', self.port_q())
-+
-+ # alice should be able to create two queues
-+ session2 = self.get_session_by_port('alice','alice', self.port_q())
-+
-+ try:
-+ session2.queue_declare(queue="queuea1")
-+ session2.queue_declare(queue="queuea2")
-+ except qpid.session.SessionException, e:
-+ self.fail("Error during queue create request");
-+
-+ # third queue should fail
-+ try:
-+ session2.queue_declare(queue="queuea3")
-+ self.fail("Should not be able to create third queue")
-+ except Exception, e:
-+ result = None
-+
-+ # bob should be able to delete a queue and create another
-+ try:
-+ session.queue_delete(queue="queue1")
-+ session.queue_declare(queue="queue3")
-+ except qpid.session.SessionException, e:
-+ self.fail("Error during queue create request");
-
- class BrokerAdmin:
- def __init__(self, broker, username=None, password=None):
-diff --git a/qpid/cpp/src/tests/run_acl_tests b/qpid/cpp/src/tests/run_acl_tests
-index 25241ad..652684f 100755
---- a/qpid/cpp/src/tests/run_acl_tests
-+++ b/qpid/cpp/src/tests/run_acl_tests
-@@ -24,22 +24,26 @@ source ./test_env.sh
- DATA_DIR=`pwd`/data_dir
- DATA_DIRI=`pwd`/data_diri
- DATA_DIRU=`pwd`/data_diru
-+DATA_DIRQ=`pwd`/data_dirq
-
- trap stop_brokers INT TERM QUIT
-
- start_brokers() {
-- ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIR --load-module $ACL_LIB --acl-file policy.acl --auth no --log-to-file local.log > qpidd.port
-+ ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIR --load-module $ACL_LIB --acl-file policy.acl --auth no --log-to-file local.log > qpidd.port
- LOCAL_PORT=`cat qpidd.port`
-- ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRI --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-ip 2 --log-to-file locali.log > qpiddi.port
-+ ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRI --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-ip 2 --log-to-file locali.log > qpiddi.port
- LOCAL_PORTI=`cat qpiddi.port`
- ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRU --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-user 2 --log-to-file localu.log > qpiddu.port
- LOCAL_PORTU=`cat qpiddu.port`
-+ ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRQ --load-module $ACL_LIB --acl-file policy.acl --auth no --max-queues-per-user 2 -t --log-to-file localq.log > qpiddq.port
-+ LOCAL_PORTQ=`cat qpiddq.port`
- }
-
- stop_brokers() {
- $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORT
- $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTI
- $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTU
-+ $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTQ
- }
-
- test_loading_acl_from_absolute_path(){
-@@ -59,20 +63,24 @@ if test -d ${PYTHON_DIR} ; then
- rm -rf $DATA_DIR
- rm -rf $DATA_DIRI
- rm -rf $DATA_DIRU
-+ rm -rf $DATA_DIRQ
- mkdir -p $DATA_DIR
- mkdir -p $DATA_DIRI
- mkdir -p $DATA_DIRU
-+ mkdir -p $DATA_DIRQ
- cp $srcdir/policy.acl $DATA_DIR
- cp $srcdir/policy.acl $DATA_DIRI
- cp $srcdir/policy.acl $DATA_DIRU
-+ cp $srcdir/policy.acl $DATA_DIRQ
- start_brokers
-- echo "Running acl tests using brokers on ports $LOCAL_PORT, $LOCAL_PORTI, and $LOCAL_PORTU"
-- $QPID_PYTHON_TEST -b localhost:$LOCAL_PORT -m acl -Dport-i=$LOCAL_PORTI -Dport-u=$LOCAL_PORTU || EXITCODE=1
-+ echo "Running acl tests using brokers on ports $LOCAL_PORT, $LOCAL_PORTI, $LOCAL_PORTU, and $LOCAL_PORTQ"
-+ $QPID_PYTHON_TEST -b localhost:$LOCAL_PORT -m acl -Dport-i=$LOCAL_PORTI -Dport-u=$LOCAL_PORTU -Dport-q=$LOCAL_PORTQ || EXITCODE=1
- stop_brokers || EXITCODE=1
- test_loading_acl_from_absolute_path || EXITCODE=1
- rm -rf $DATA_DIR
- rm -rf $DATA_DIRI
- rm -rf $DATA_DIRU
-+ rm -rf $DATA_DIRQ
- exit $EXITCODE
- fi
-
---
-1.7.1
-
-From 423d492e38f4214a2ca1d87f0ee7347203785fef Mon Sep 17 00:00:00 2001
-From: Chuck Rolke
-Date: Tue, 21 Aug 2012 15:21:26 -0400
-Subject: [PATCH 12/19] QPID-2393 Count queues per user.
- Move queue counting functions out of connection counting files
- and into new files.
-
----
- qpid/cpp/src/qpid/acl/AclResourceCounter.cpp | 167 ++++++++++++++++++++++++++
- qpid/cpp/src/qpid/acl/AclResourceCounter.h | 77 ++++++++++++
- 2 files changed, 244 insertions(+), 0 deletions(-)
- create mode 100644 qpid/cpp/src/qpid/acl/AclResourceCounter.cpp
- create mode 100644 qpid/cpp/src/qpid/acl/AclResourceCounter.h
-
-diff --git a/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp b/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp
-new file mode 100644
-index 0000000..98bc144
---- /dev/null
-+++ b/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp
-@@ -0,0 +1,167 @@
-+/*
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#include "AclResourceCounter.h"
-+#include "Acl.h"
-+#include "qpid/log/Statement.h"
-+#include "qpid/sys/Mutex.h"
-+#include
-+#include
-+
-+using namespace qpid::sys;
-+
-+namespace qpid {
-+namespace acl {
-+
-+//
-+// This module approves various resource creation requests:
-+// Queues
-+//
-+
-+
-+//
-+//
-+//
-+ResourceCounter::ResourceCounter(Acl& a, uint16_t ql) :
-+ acl(a), queueLimit(ql) {
-+ QPID_LOG(critical, "ACL RESOURCE_COUNTER queueLimit:" << queueLimit);
-+ }
-+
-+ResourceCounter::~ResourceCounter() {}
-+
-+
-+//
-+// limitApproveLH
-+//
-+// Resource creation approver.
-+// If user is under limit increment count and return true.
-+// Called with lock held.
-+//
-+bool ResourceCounter::limitApproveLH(
-+ const std::string& theTitle,
-+ countsMap_t& theMap,
-+ const std::string& theName,
-+ uint16_t theLimit,
-+ bool emitLog) {
-+
-+ bool result(true);
-+ if (theLimit > 0) {
-+ uint16_t count;
-+ countsMap_t::iterator eRef = theMap.find(theName);
-+ if (eRef != theMap.end()) {
-+ count = (uint16_t)(*eRef).second;
-+ result = count < theLimit;
-+ if (result) {
-+ count += 1;
-+ (*eRef).second = count;
-+ }
-+ } else {
-+ // Not found
-+ theMap[theName] = count = 1;
-+ }
-+ if (emitLog) {
-+ QPID_LOG(trace, theTitle << theName
-+ << " limit=" << theLimit
-+ << " curValue=" << count
-+ << " result=" << (result ? "allow" : "deny"));
-+ }
-+ }
-+ return result;
-+}
-+
-+
-+//
-+// releaseLH
-+//
-+// Decrement the name's count in map.
-+// called with dataLock already taken
-+//
-+void ResourceCounter::releaseLH(
-+ countsMap_t& theMap, const std::string& theName, uint16_t theLimit) {
-+
-+ if (theLimit > 0) {
-+ countsMap_t::iterator eRef = theMap.find(theName);
-+ if (eRef != theMap.end()) {
-+ uint16_t count = (uint16_t) (*eRef).second;
-+ assert (count > 0);
-+ if (1 == count) {
-+ theMap.erase (eRef);
-+ } else {
-+ (*eRef).second = count - 1;
-+ }
-+ } else {
-+ // User had no connections.
-+ QPID_LOG(notice, "ACL ResourceCounter Connection for '" << theName
-+ << "' not found in connection count pool");
-+ }
-+ }
-+}
-+
-+
-+//
-+// approveCreateQueue
-+// Count an attempted queue creation by this user.
-+// Disapprove if over limit.
-+//
-+bool ResourceCounter::approveCreateQueue(const std::string& userId, const std::string& queueName)
-+{
-+ Mutex::ScopedLock locker(dataLock);
-+
-+ QPID_LOG(critical, "DEV HACK approveCreateQueue ----------- userId:" << userId << ", queueName:" << queueName);
-+
-+ bool okByQ = limitApproveLH("ACL Queue creation approver. userId:", queuePerUserMap, userId, queueLimit, true);
-+
-+ if (okByQ) {
-+ // Queue is owned by this userId
-+ queueOwnerMap[queueName] = userId;
-+
-+ QPID_LOG(trace, "ACL create queue approved for user '" << userId
-+ << "' queue '" << queueName << "'");
-+ } else {
-+
-+ QPID_LOG(error, "Client max queue count limit of " << queueLimit
-+ << " exceeded by '" << userId << "' creating queue '"
-+ << queueName << "'. Queue creation denied.");
-+ }
-+ return okByQ;
-+}
-+
-+
-+//
-+// recordDestroyQueue
-+// Return a destroyed queue to a user's quota
-+//
-+void ResourceCounter::recordDestroyQueue(const std::string& queueName)
-+{
-+ Mutex::ScopedLock locker(dataLock);
-+
-+ queueOwnerMap_t::iterator eRef = queueOwnerMap.find(queueName);
-+ if (eRef != queueOwnerMap.end()) {
-+ releaseLH(queuePerUserMap, (*eRef).second, queueLimit);
-+
-+ queueOwnerMap.erase(eRef);
-+ } else {
-+ QPID_LOG(notice, "ACL owner for queue '" << queueName
-+ << "' not found in owner map");
-+ }
-+}
-+
-+}} // namespace qpid::acl
-diff --git a/qpid/cpp/src/qpid/acl/AclResourceCounter.h b/qpid/cpp/src/qpid/acl/AclResourceCounter.h
-new file mode 100644
-index 0000000..061ced9
---- /dev/null
-+++ b/qpid/cpp/src/qpid/acl/AclResourceCounter.h
-@@ -0,0 +1,77 @@
-+#ifndef QPID_ACL_RESOURCECOUNTER_H
-+#define QPID_ACL_RESOURCECOUNTER_H
-+
-+/*
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#include "qpid/sys/Mutex.h"
-+#include
-+
-+#include