/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.binding.lifx.internal.protocol;
import java.util.HashMap;
import java.util.Map;
/**
* A static factory for registering packet types that may be received and
* dispatched to client cod * request types, like {@code PowerStateRequest}) or types received only via UDP
* e. Packet handlers (used to construct actual packet
* instances) may be retrieved via their packet type.
*
* @author Tim Buckley - Initial Contribution
* @author Karel Goderis - Enhancement for the V2 LIFX Firmware and LAN Protocol Specification
* @author Wouter Born - Support LIFX 2016 product line-up and infrared functionality
*/
public class PacketFactory {
private static PacketFactory instance;
public synchronized static PacketFactory getInstance() {
if (instance == null) {
instance = new PacketFactory();
}
return instance;
}
private final Map<Integer, PacketHandler<?>> handlers;
private PacketFactory() {
handlers = new HashMap<>();
register(AcknowledgementResponse.class);
register(EchoRequestResponse.class);
register(GetColorZonesRequest.class);
register(GetEchoRequest.class);
register(GetGroupRequest.class);
register(GetHostFirmwareRequest.class);
register(GetHostInfoRequest.class);
register(GetInfoRequest.class);
register(GetLabelRequest.class);
register(GetLightInfraredRequest.class);
register(GetLightPowerRequest.class);
register(GetLocationRequest.class);
register(GetPowerRequest.class);
register(GetRequest.class);
register(GetServiceRequest.class);
register(GetTagLabelsRequest.class);
register(GetTagsRequest.class);
register(GetVersionRequest.class);
register(GetWifiFirmwareRequest.class);
register(GetWifiInfoRequest.class);
register(SetColorRequest.class);
register(SetColorZonesRequest.class);
register(SetDimAbsoluteRequest.class);
register(SetLabelRequest.class);
register(SetLightInfraredRequest.class);
register(SetLightPowerRequest.class);
register(SetPowerRequest.class);
register(SetTagsRequest.class);
register(StateGroupResponse.class);
register(StateHostFirmwareResponse.class);
register(StateHostInfoResponse.class);
register(StateInfoResponse.class);
register(StateLabelResponse.class);
register(StateLightInfraredResponse.class);
register(StateLightPowerResponse.class);
register(StateLocationResponse.class);
register(StateMultiZoneResponse.class);
register(StatePowerResponse.class);
register(StateResponse.class);
register(StateServiceResponse.class);
register(StateVersionResponse.class);
register(StateWifiFirmwareResponse.class);
register(StateWifiInfoResponse.class);
register(StateZoneResponse.class);
register(TagLabelsResponse.class);
register(TagsResponse.class);
}
/**
* Registers a packet handler for the given packet type.
*
* @param type the type to register
* @param handler the packet handler to associate with the type
*/
public final void register(int type, PacketHandler<?> handler) {
handlers.put(type, handler);
}
/**
* Registers a new generic packet handler for the given packet class. The
* packet class must meet the criteria for {@link GenericHandler};
* specifically, it must have an no-argument constructor and require no
* parsing logic outside of an invocation of
* {@link Packet#parse(java.nio.ByteBuffer)}.
*
* @param type the type of the packet to register
* @param clazz the class of the packet to register
*/
public final void register(int type, Class<? extends Packet> clazz) {
handlers.put(type, new GenericHandler<>(clazz));
}
/**
* Registers a generic packet type. All requirements of
* {@link GenericHandler} must met; specifically, classes must have a
* no-args constructor and require no additional parsing logic.
* Additionally, a public static integer {@code TYPE} field must be defined.
*
* @param <T> the packet type to register
* @param clazz the packet class to register
*/
public final <T extends Packet> void register(Class<T> clazz) {
GenericHandler<T> handler = new GenericHandler<>(clazz);
if (!handler.isTypeFound()) {
throw new IllegalArgumentException("Unable to register generic packet with no TYPE field.");
}
handlers.put(handler.getType(), handler);
}
/**
* Gets a registered handler for the given packet type, if any exists. If
* no matching handler can be found, {@code null} is returned.
*
* @param packetType the packet type of the handler to retrieve
* @return a packet handler, or null
*/
public PacketHandler<?> getHandler(int packetType) {
return handlers.get(packetType);
}
public static PacketHandler<?> createHandler(int packetType) {
return getInstance().getHandler(packetType);
}
}