/******************************************************************************
* JBoss, a division of Red Hat *
* Copyright 2008, Red Hat Middleware, LLC, and individual *
* contributors as indicated by the @authors tag. See the *
* copyright.txt in the distribution for a full listing of *
* individual contributors. *
* *
* This is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation; either version 2.1 of *
* the License, or (at your option) any later version. *
* *
* This software is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this software; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
******************************************************************************/
package org.gatein.pc.test.controller.unit;
import org.gatein.pc.api.Mode;
import org.gatein.pc.api.WindowState;
import org.gatein.common.io.Serialization;
import org.gatein.pc.api.StateString;
import org.gatein.pc.controller.state.PageNavigationalState;
import org.gatein.pc.controller.state.StateControllerContext;
import org.gatein.pc.controller.state.WindowNavigationalState;
import javax.xml.namespace.QName;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Implement serialization of a page navigational state in a compact manner.
*
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 630 $
*/
public class PageNavigationalStateSerialization implements Serialization<PageNavigationalState>
{
/** . */
private static final Map<org.gatein.pc.api.WindowState, Integer> windowStateToCode = new HashMap<WindowState, Integer>();
/** . */
private static final Map<Mode, Integer> modeToCode = new HashMap<Mode, Integer>();
/** . */
private static final Map<Integer, org.gatein.pc.api.WindowState> codeToWindowState = new HashMap<Integer, org.gatein.pc.api.WindowState>();
/** . */
private static final Map<Integer, org.gatein.pc.api.Mode> codeToMode = new HashMap<Integer, Mode>();
static
{
windowStateToCode.put(WindowState.NORMAL, 1);
windowStateToCode.put(org.gatein.pc.api.WindowState.MINIMIZED, 2);
windowStateToCode.put(WindowState.MAXIMIZED, 3);
codeToWindowState.put(1, WindowState.NORMAL);
codeToWindowState.put(2, org.gatein.pc.api.WindowState.MINIMIZED);
codeToWindowState.put(3, org.gatein.pc.api.WindowState.MAXIMIZED);
modeToCode.put(Mode.VIEW, 1);
modeToCode.put(org.gatein.pc.api.Mode.EDIT, 2);
modeToCode.put(Mode.HELP, 3);
codeToMode.put(1, Mode.VIEW);
codeToMode.put(2, Mode.EDIT);
codeToMode.put(3, Mode.HELP);
}
/** . */
private final StateControllerContext context;
public PageNavigationalStateSerialization(StateControllerContext context)
{
if (context == null)
{
throw new IllegalArgumentException();
}
this.context = context;
}
public void serialize(PageNavigationalState pageNavigationalState, OutputStream out) throws IOException, IllegalArgumentException
{
DataOutputStream data = out instanceof DataOutputStream ? (DataOutputStream)out : new DataOutputStream(out);
//
data.writeInt(pageNavigationalState.getWindowIds().size());
for (String windowId : pageNavigationalState.getWindowIds())
{
data.writeUTF(windowId);
WindowNavigationalState windowNS = pageNavigationalState.getWindowNavigationalState(windowId);
byte header = 0;
int decision = 0;
if (windowNS.getPortletNavigationalState() != null)
{
header |= 1;
decision |= 1;
}
if (windowNS.getWindowState() != null)
{
Integer value = windowStateToCode.get(windowNS.getWindowState());
if (value != null)
{
header |= value << 1;
}
else
{
header |= 4 << 1;
decision |= 2;
}
}
if (windowNS.getMode() != null)
{
Integer value = modeToCode.get(windowNS.getMode());
if (value != null)
{
header |= value << 4;
}
else
{
header |= 4 << 4;
decision |= 4;
}
}
data.writeByte(header);
if ((decision & 1) != 0)
{
windowNS.getPortletNavigationalState().writeTo(data);
}
if ((decision & 2) != 0)
{
data.writeUTF(windowNS.getWindowState().toString());
}
if ((decision & 4) != 0)
{
data.writeUTF(windowNS.getMode().toString());
}
}
//
Set<QName> publicNames = pageNavigationalState.getPublicNames();
data.writeInt(publicNames.size());
for (QName name : pageNavigationalState.getPublicNames())
{
data.writeUTF(name.getNamespaceURI());
data.writeUTF(name.getLocalPart());
String[] values = pageNavigationalState.getPublicNavigationalState(name);
int length = values.length;
data.writeInt(length);
for (String value : values)
{
data.writeUTF(value);
}
}
// Need to flush before returning otherwise bytes may stay in the buffer when we allocated
// a data stream
data.flush();
}
public PageNavigationalState unserialize(InputStream in) throws IOException, IllegalArgumentException
{
DataInputStream data = in instanceof DataInputStream ? (DataInputStream)in : new DataInputStream(in);
//
PageNavigationalState pageNS = new PageNavigationalState(true);
//
int size = data.readInt();
while (size-- > 0)
{
String windowId = data.readUTF();
byte header = data.readByte();
StateString portletNS = null;
if ((header & 1) != 0)
{
portletNS = StateString.create(data);
}
org.gatein.pc.api.WindowState windowState = null;
int windowStateHeader = (header & (7 << 1)) >> 1;
switch (windowStateHeader)
{
case 0:
break;
case 4:
windowState = org.gatein.pc.api.WindowState.create(data.readUTF());
break;
default:
windowState = codeToWindowState.get(windowStateHeader);
}
org.gatein.pc.api.Mode mode = null;
int modeStateHeader = (header & (7 << (1 + 3))) >> (1 + 3);
switch (modeStateHeader)
{
case 0:
break;
case 4:
mode = Mode.create(data.readUTF());
break;
default:
mode = codeToMode.get(modeStateHeader);
}
WindowNavigationalState windowNS = new WindowNavigationalState(portletNS, mode, windowState);
pageNS.setWindowNavigationalState(windowId, windowNS);
}
//
size = data.readInt();
while (size-- > 0)
{
String namespaceURI = data.readUTF();
String localName = data.readUTF();
QName name = new QName(namespaceURI, localName);
int length = data.readInt();
String[] values = new String[length];
for (int i = 0; i < length; i++)
{
values[i] = data.readUTF();
}
pageNS.setPublicNavigationalState(name, values);
}
//
return pageNS;
}
}