/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openengsb.core.services.xlink;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openengsb.core.api.OsgiUtilsService;
import org.openengsb.core.api.model.ModelDescription;
import org.openengsb.core.api.model.OpenEngSBModelEntry;
import org.openengsb.core.api.xlink.model.XLinkConnector;
import org.openengsb.core.api.xlink.model.XLinkConnectorRegistration;
import org.openengsb.core.api.xlink.model.XLinkConnectorView;
import org.openengsb.core.api.xlink.model.XLinkConstants;
import org.openengsb.core.api.xlink.model.XLinkUrlBlueprint;
import org.openengsb.core.api.xlink.model.XLinkUrlKeyNames;
import org.openengsb.core.ekb.api.ModelRegistry;
import org.openengsb.core.util.ModelUtils;
/**
* Static util class for xlink, defining XLink keyNames and UtilMethods.
* Provides the preparaition of XLinkTemplates and demonstrates how
* valid XLink-Urls are generated.
*/
public final class XLinkUtils {
private XLinkUtils() {
}
// @extract-start XLinkUtilsPrepareTemplate
/**
* Prepares the XLinkTemplate before it is transmitted to the remote tool.
* <br/><br/>
* The baseUrl is prepared and the KeyNames are added. <br/>
* The models are assigned to the views (yet in an naive order). <br/>
* The ConnectorId/value combination and the ViewId-Key are also added to the Template to enable
* Local Switching.
*/
public static XLinkUrlBlueprint prepareXLinkTemplate(String baseUrl,
String connectorId,
Map<ModelDescription, XLinkConnectorView[]> modelsToViews,
int expirationDays,
XLinkConnector[] registeredTools) {
baseUrl +=
"?" + XLinkConstants.XLINK_EXPIRATIONDATE_KEY + "=" + urlEncodeParameter(getExpirationDate(expirationDays));
String connectorIdParam = XLinkConstants.XLINK_CONNECTORID_KEY + "=" + urlEncodeParameter(connectorId);
Map<String, ModelDescription> viewToModels = assigneModelsToViews(modelsToViews);
return
new XLinkUrlBlueprint(baseUrl,
viewToModels,
registeredTools,
connectorIdParam,
new XLinkUrlKeyNames()
);
}
/**
* Naive model to view assignment.
* The current model is choosen for the first occurence of the view.
*/
private static Map<String, ModelDescription> assigneModelsToViews(Map<ModelDescription,
XLinkConnectorView[]> modelsToViews) {
HashMap<String, ModelDescription> viewsToModels = new HashMap<String, ModelDescription>();
for (ModelDescription modelInfo : modelsToViews.keySet()) {
List<XLinkConnectorView> currentViewList = Arrays.asList(modelsToViews.get(modelInfo));
for (XLinkConnectorView view : currentViewList) {
if (!viewsToModels.containsKey(view.getViewId())) {
viewsToModels.put(view.getViewId(), modelInfo);
}
}
}
return viewsToModels;
}
/**
* Returns a future Date-String in the format 'yyyyMMddkkmmss'.
*/
private static String getExpirationDate(int futureDays) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, futureDays);
Format formatter = new SimpleDateFormat(XLinkConstants.DATEFORMAT);
return formatter.format(calendar.getTime());
}
// @extract-end
/**
* Sets the value, of the field defined in the OpenEngSBModelEntry, the the given model,
* with reflection.
*/
public static void setValueOfModel(Object model, OpenEngSBModelEntry entry, Object value) throws
NoSuchFieldException,
IllegalArgumentException,
IllegalAccessException {
Class clazz = model.getClass();
Field field = clazz.getDeclaredField(entry.getKey());
field.setAccessible(true);
field.set(model, value);
}
/**
* Returns an empty instance to a given Classobject.
* Returns null, if an error happens during the instantiation.
*/
public static Object createEmptyInstanceOfModelClass(Class clazzObject) {
return createInstanceOfModelClass(clazzObject,
new ArrayList<OpenEngSBModelEntry>());
}
/**
* Returns an instance to a given Classobject and a List of OpenEngSBModelEntries.
* Returns null, if an error happens during the instantiation.
*/
public static Object createInstanceOfModelClass(Class clazzObject,
List<OpenEngSBModelEntry> entries) {
return ModelUtils.createModel(clazzObject, entries);
}
/**
* Returns the Classobject to a given clazzString and a given version.
* Throws a ClassNotFoundException if the Class/Version pair is not found.
*/
public static Class getClassOfOpenEngSBModel(String clazz,
String version,
OsgiUtilsService serviceFinder) throws ClassNotFoundException {
ModelRegistry registry = serviceFinder.getService(ModelRegistry.class);
ModelDescription modelDescription = new ModelDescription(clazz, version);
Class clazzObject = registry.loadModel(modelDescription);
return clazzObject;
}
/**
* Returns a Calendarobject to a given dateString in the Format 'DATEFORMAT'.
* If the given String is of the wrong format, null is returned.
* @see XLinkUtils#DATEFORMAT
*/
public static Calendar dateStringToCalendar(String dateString) {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat(XLinkConstants.DATEFORMAT);
try {
calendar.setTime(formatter.parse(dateString));
} catch (Exception ex) {
return null;
}
return calendar;
}
/**
* Encodes a given Parameter in UTF-8.
*/
private static String urlEncodeParameter(String parameter) {
try {
return URLEncoder.encode(parameter, "UTF-8");
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(XLinkUtils.class.getName()).log(Level.SEVERE, null, ex);
}
return parameter;
}
/**
* Returns a distinct List of all RemoteToolViews, contained in a RemoteToolRegistration.
* @see RemoteToolView
* @see RemoteToolRegistration
*/
public static XLinkConnectorView[] getViewsOfRegistration(XLinkConnectorRegistration registration) {
List<XLinkConnectorView> viewsOfRegistration = new ArrayList<XLinkConnectorView>();
Map<ModelDescription, XLinkConnectorView[]> modelsToViews = registration.getModelsToViews();
for (XLinkConnectorView[] views : modelsToViews.values()) {
for (int i = 0; i < views.length; i++) {
XLinkConnectorView view = views[i];
if (!viewsOfRegistration.contains(view)) {
viewsOfRegistration.add(view);
}
}
}
return viewsOfRegistration.toArray(new XLinkConnectorView[0]);
}
/**
* Returns a list of RemoteTools to a list of RemoteToolRegistrations.
* The list of RemoteTool can be sent to a remote host. A RemoteToolRegistration
* is for internal usage only.
* @see RemoteToolRegistration
* @see RemoteTool
*/
public static XLinkConnector[] getLocalToolFromRegistrations(List<XLinkConnectorRegistration> registrations) {
List<XLinkConnector> tools = new ArrayList<XLinkConnector>();
for (XLinkConnectorRegistration registration : registrations) {
XLinkConnector newLocalTools
= new XLinkConnector(
registration.getConnectorId(),
registration.getToolName(),
getViewsOfRegistration(registration));
tools.add(newLocalTools);
}
return tools.toArray(new XLinkConnector[0]);
}
}