class TemplateServiceImpl extends RemoteServiceServlet implements TemplateService {

	@Override
	public GUITemplate save(GUITemplate template) throws ServerException {
		Session session = ServiceUtil.validateSession(getThreadLocalRequest());

		TemplateDAO dao = (TemplateDAO) Context.get().getBean(TemplateDAO.class);
		try {
			Template templ;
			if (template.getId() != 0) {
				templ = dao.findById(template.getId());
				dao.initialize(templ);
			} else {
				templ = new Template();
			}

			templ.setTenantId(session.getTenantId());
			templ.setName(template.getName());
			templ.setDescription(template.getDescription());
			templ.setReadonly(template.isReadonly() ? 1 : 0);
			templ.setType(template.getType());

			Map<String, Attribute> attrs = new HashMap<String, Attribute>();
			if (template.getAttributes() != null && template.getAttributes().length > 0) {
				templ.getAttributes().clear();
				for (GUIAttribute attribute : template.getAttributes()) {
					if (attribute != null) {
						Attribute att = new Attribute();
						att.setMandatory(attribute.isMandatory() ? 1 : 0);
						att.setHidden(attribute.isHidden() ? 1 : 0);
						att.setMultiple(attribute.isMultiple() ? 1 : 0);
						att.setParent(attribute.getParent());
						att.setType(attribute.getType());
						att.setLabel(attribute.getLabel());
						att.setEditor(attribute.getEditor());
						att.setStringValue(attribute.getStringValue());
						att.setStringValues(attribute.getStringValues());
						att.setSetId(attribute.getSetId());
						att.setPosition(attribute.getPosition());
						if (StringUtils.isEmpty(attribute.getLabel()))
							att.setLabel(attribute.getName());
						if (attribute.getValue() instanceof String)
							att.setStringValue(attribute.getStringValue());
						else if (attribute.getValue() instanceof Long)
							att.setIntValue(attribute.getIntValue());
						else if (attribute.getValue() instanceof Double)
							att.setDoubleValue(attribute.getDoubleValue());
						else if (attribute.getValue() instanceof Date)
							att.setDateValue(attribute.getDateValue());
						else if (attribute.getValue() instanceof Boolean)
							att.setBooleanValue(attribute.getBooleanValue());
						attrs.put(attribute.getName(), att);
					}
				}
			}
			if (attrs.size() > 0)
				templ.setAttributes(attrs);

			boolean stored = dao.store(templ);
			if (!stored)
				throw new Exception(
						String.format("Template has not been %s", templ.getId() != 0L ? "updated" : "stored"));

			template.setId(templ.getId());
		} catch (Throwable t) {
			return (GUITemplate) ServiceUtil.throwServerException(session, log, t);
		}

		return template;
	}

}