/*
* Copyright 2014-2016 CyberVision, Inc.
*
* 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.
*/
package org.kaaproject.kaa.server.control.service.sdk;
import static org.kaaproject.kaa.common.dto.admin.SdkPlatform.JAVA;
import org.apache.avro.Schema;
import org.apache.avro.compiler.specific.SpecificCompiler;
import org.apache.avro.compiler.specific.SpecificCompiler.FieldVisibility;
import org.apache.avro.generic.GenericData.StringType;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.kaaproject.kaa.common.dto.admin.SdkPlatform;
import org.kaaproject.kaa.common.dto.admin.SdkProfileDto;
import org.kaaproject.kaa.common.dto.file.FileData;
import org.kaaproject.kaa.server.common.Environment;
import org.kaaproject.kaa.server.common.Version;
import org.kaaproject.kaa.server.common.zk.gen.BootstrapNodeInfo;
import org.kaaproject.kaa.server.control.service.sdk.compiler.JavaDynamicBean;
import org.kaaproject.kaa.server.control.service.sdk.compiler.JavaDynamicCompiler;
import org.kaaproject.kaa.server.control.service.sdk.compress.ZipEntryData;
import org.kaaproject.kaa.server.control.service.sdk.event.EventFamilyMetadata;
import org.kaaproject.kaa.server.control.service.sdk.event.JavaEventClassesGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import javax.tools.JavaFileObject.Kind;
public class JavaSdkGenerator extends SdkGenerator {
private static final Logger LOG = LoggerFactory.getLogger(JavaSdkGenerator.class);
private static final String JAVA_SDK_DIR = "sdk/java";
private static final String JAVA_SDK_PREFIX = "kaa-java-ep-sdk-";
private static final String ANDROID_SDK_DIR = "sdk/android";
private static final String ANDROID_SDK_PREFIX = "kaa-android-ep-sdk-";
private static final String CLIENT_PROPERTIES = "client.properties";
private static final String BUILD_VERSION = "build.version";
private static final String BUILD_COMMIT_HASH = "build.commit_hash";
private static final String BOOTSTRAP_SERVERS_PROPERTY = "transport.bootstrap.servers";
private static final String SDK_TOKEN_PROPERTY = "sdk_token";
private static final String CONFIG_DATA_DEFAULT_PROPERTY = "config.data.default";
private static final String CONFIG_SCHEMA_DEFAULT_PROPERTY = "config.schema.default";
private static final String KAA_CLIENT_SOURCE_TEMPLATE = "sdk/java/KaaClient.java.template";
private static final String BASE_KAA_CLIENT_SOURCE_TEMPLATE =
"sdk/java/BaseKaaClient.java.template";
private static final String CONFIGURATION_MANAGER_SOURCE_TEMPLATE =
"sdk/java/cf/ConfigurationManager.java.template";
private static final String CONFIGURATION_MANAGER_IMPL_SOURCE_TEMPLATE =
"sdk/java/cf/ResyncConfigurationManager.java.template";
private static final String CONFIGURATION_LISTENER_SOURCE_TEMPLATE =
"sdk/java/cf/ConfigurationListener.java.template";
private static final String CONFIGURATION_DESERIALIZER_SOURCE_TEMPLATE =
"sdk/java/cf/ConfigurationDeserializer.java.template";
private static final String NOTIFICATION_LISTENER_SOURCE_TEMPLATE =
"sdk/java/nf/NotificationListener.java.template";
private static final String NOTIFICATION_DESERIALIZER_SOURCE_TEMPLATE =
"sdk/java/nf/NotificationDeserializer.java.template";
private static final String PROFILE_CONTAINER_SOURCE_TEMPLATE =
"sdk/java/profile/ProfileContainer.java.template";
private static final String DEFAULT_PROFILE_CONTAINER_SOURCE_TEMPLATE =
"sdk/java/profile/DefaultProfileContainer.java.template";
private static final String PROFILE_SERIALIZER_SOURCE_TEMPLATE =
"sdk/java/profile/ProfileSerializer.java.template";
private static final String DEFAULT_PROFILE_SERIALIZER_SOURCE_TEMPLATE =
"sdk/java/profile/DefaultProfileSerializer.java.template";
private static final String LOG_RECORD_SOURCE_TEMPLATE =
"sdk/java/log/LogRecord.java.template";
private static final String LOG_COLLECTOR_INTERFACE_TEMPLATE =
"sdk/java/log/LogCollector.java.template";
private static final String LOG_COLLECTOR_SOURCE_TEMPLATE =
"sdk/java/log/DefaultLogCollector.java.template";
private static final String USER_VERIFIER_CONSTANTS_SOURCE_TEMPLATE =
"sdk/java/event/UserVerifierConstants.java.template";
private static final String PROFILE_CONTAINER = "ProfileContainer";
private static final String DEFAULT_PROFILE_CONTAINER = "DefaultProfileContainer";
private static final String PROFILE_SERIALIZER = "ProfileSerializer";
private static final String CONFIGURATION_MANAGER = "ConfigurationManager";
private static final String CONFIGURATION_MANAGER_IMPL = "ResyncConfigurationManager";
private static final String CONFIGURATION_LISTENER = "ConfigurationListener";
private static final String CONFIGURATION_DESERIALIZER = "ConfigurationDeserializer";
private static final String NOTIFICATION_LISTENER = "NotificationListener";
private static final String NOTIFICATION_DESERIALIZER = "NotificationDeserializer";
private static final String USER_VERIFIER_CONSTANTS = "UserVerifierConstants";
private static final int DEFAULT_SCHEMA_VERSION = 1;
private static final int DEFAULT_PROFILE_SCHEMA_VERSION = 0;
private static final String KAA_CLIENT = "KaaClient";
private static final String BASE_KAA_CLIENT = "BaseKaaClient";
private static final String LOG_RECORD = "LogRecord";
private static final String LOG_COLLECTOR_INTERFACE = "LogCollector";
private static final String LOG_COLLECTOR_SOURCE = "DefaultLogCollector";
private static final String PROFILE_CLASS_PACKAGE_VAR = "\\$\\{profile_class_package\\}";
private static final String PROFILE_CLASS_VAR = "\\$\\{profile_class\\}";
private static final String CONFIGURATION_CLASS_PACKAGE_VAR =
"\\$\\{configuration_class_package\\}";
private static final String CONFIGURATION_CLASS_VAR = "\\$\\{configuration_class\\}";
private static final String NOTIFICATION_CLASS_PACKAGE_VAR =
"\\$\\{notification_class_package\\}";
private static final String NOTIFICATION_CLASS_VAR = "\\$\\{notification_class\\}";
private static final String LOG_RECORD_CLASS_PACKAGE_VAR = "\\$\\{log_record_class_package\\}";
private static final String LOG_RECORD_CLASS_VAR = "\\$\\{log_record_class\\}";
private static final String DEFAULT_USER_VERIFIER_TOKEN_VAR =
"\\$\\{default_user_verifier_token\\}";
private static final String JAVA_SOURCE_COMPILER_RELEASE = "7";
private static final String JAVA_TARGET_COMPILER_RELEASE = "7";
private static final SecureRandom RANDOM = new SecureRandom();
private final SdkPlatform sdkPlatform;
public JavaSdkGenerator(SdkPlatform sdkPlatform) {
this.sdkPlatform = sdkPlatform;
}
/**
* Generate schema class.
*
* @param schema the schema
* @param uniqueSchemas the unique schemas
* @return the list
* @throws IOException Signals that an I/O exception has occurred.
*/
public static List<JavaDynamicBean> generateSchemaSources(
Schema schema, Map<String, Schema> uniqueSchemas) throws IOException {
SpecificCompiler compiler = new SpecificCompiler(schema);
compiler.setStringType(StringType.String);
compiler.setFieldVisibility(FieldVisibility.PRIVATE);
File tmpdir = new File(System.getProperty("java.io.tmpdir"));
long value = RANDOM.nextLong();
if (value == Long.MIN_VALUE) {
// corner case
value = 0;
} else {
value = Math.abs(value);
}
File tmpOutputDir = new File(tmpdir, "tmp-gen-" + Long.toString(value));
tmpOutputDir.mkdirs();
compiler.compileToDestination(null, tmpOutputDir);
List<JavaDynamicBean> sources = getJavaSources(tmpOutputDir, uniqueSchemas);
tmpOutputDir.delete();
return sources;
}
/**
* Gets the java sources.
*
* @param srcDir the src dir
* @return the java sources
* @throws IOException Signals that an I/O exception has occurred.
*/
private static List<JavaDynamicBean> getJavaSources(
File srcDir, Map<String, Schema> uniqueSchemas) throws IOException {
List<JavaDynamicBean> result = new ArrayList<JavaDynamicBean>();
File[] files = srcDir.listFiles();
for (File f : files) {
if (f.isDirectory()) {
result.addAll(getJavaSources(f, uniqueSchemas));
} else if (f.getName().endsWith(Kind.SOURCE.extension)) {
int index = f.getName().indexOf('.');
String className = f.getName().substring(0, index);
String sourceCode = readFile(f);
String classPackageAndName = "";
String[] sourceLines = sourceCode.split("\n");
for (String ss : sourceLines) {
if (ss.startsWith("package ")) {
classPackageAndName = ss
.replace("package ", "")
.trim()
.replaceAll(";", ".") + className;
break;
}
}
if (uniqueSchemas.containsKey(classPackageAndName)) {
uniqueSchemas.remove(classPackageAndName);
JavaDynamicBean sourceObject = new JavaDynamicBean(className, sourceCode);
result.add(sourceObject);
}
}
}
return result;
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.control.service.sdk.SdkGenerator#generateSdk
* (java.lang.String, java.util.List, java.lang.String, int, int, int,
* java.lang.String, java.lang.String, java.lang.String, byte[],
* java.util.List)
*/
@Override
public FileData generateSdk(String buildVersion, List<BootstrapNodeInfo> bootstrapNodes,
SdkProfileDto sdkProfile,
String profileSchemaBody,
String notificationSchemaBody,
String configurationProtocolSchemaBody,
String configurationSchemaBody,
byte[] defaultConfigurationData,
List<EventFamilyMetadata> eventFamilies,
String logSchemaBody) throws Exception {
final String sdkToken = sdkProfile.getToken();
final Integer profileSchemaVersion = sdkProfile.getProfileSchemaVersion();
final Integer notificationSchemaVersion = sdkProfile.getNotificationSchemaVersion();
final Integer logSchemaVersion = sdkProfile.getLogSchemaVersion();
final Schema configurationSchema = new Schema.Parser().parse(configurationSchemaBody);
final Schema profileSchema = new Schema.Parser().parse(profileSchemaBody);
final Schema notificationSchema = new Schema.Parser().parse(notificationSchemaBody);
final Schema logSchema = new Schema.Parser().parse(logSchemaBody);
List<String> flatEventClassCtlSchemas = new ArrayList<>();
eventFamilies.forEach(ecf -> flatEventClassCtlSchemas.addAll(ecf.getRawCtlsSchemas()));
List<Schema> eventClassCtlSchemas = new LinkedList<>();
if (!flatEventClassCtlSchemas.isEmpty()) {
for (String flatCtlSchema : flatEventClassCtlSchemas) {
Schema eventClassCtlSchema = new Schema.Parser().parse(flatCtlSchema);
eventClassCtlSchemas.add(eventClassCtlSchema);
}
}
List<Schema> schemasToCheck = new LinkedList<>();
schemasToCheck.add(configurationSchema);
schemasToCheck.add(profileSchema);
schemasToCheck.add(notificationSchema);
schemasToCheck.add(logSchema);
schemasToCheck.addAll(eventClassCtlSchemas);
Map<String, Schema> uniqueSchemasMap = SchemaUtil.getUniqueSchemasMap(schemasToCheck);
String sdkTemplateLocation;
if (sdkPlatform == JAVA) {
sdkTemplateLocation = Environment.getServerHomeDir()
+ "/" + JAVA_SDK_DIR + "/" + JAVA_SDK_PREFIX + buildVersion + ".jar";
LOG.debug("Lookup Java SDK template: {}", sdkTemplateLocation);
} else { // ANDROID
sdkTemplateLocation = Environment.getServerHomeDir()
+ "/" + ANDROID_SDK_DIR + "/" + ANDROID_SDK_PREFIX + buildVersion + ".jar";
LOG.debug("Lookup Android SDK template: {}", sdkTemplateLocation);
}
File sdkTemplateFile = new File(sdkTemplateLocation);
ZipFile templateArhive = new ZipFile(sdkTemplateFile);
Map<String, ZipEntryData> replacementData = new HashMap<String, ZipEntryData>();
ZipEntry clientPropertiesEntry = templateArhive.getEntry(CLIENT_PROPERTIES);
byte[] clientPropertiesData = generateClientProperties(
templateArhive.getInputStream(clientPropertiesEntry), bootstrapNodes,
sdkToken, configurationProtocolSchemaBody, defaultConfigurationData);
replacementData.put(CLIENT_PROPERTIES, new ZipEntryData(
new ZipEntry(CLIENT_PROPERTIES),
clientPropertiesData)
);
List<JavaDynamicBean> javaSources = new ArrayList<JavaDynamicBean>();
String configurationClassName = configurationSchema.getName();
String configurationClassPackage = configurationSchema.getNamespace();
javaSources.addAll(generateSchemaSources(configurationSchema, uniqueSchemasMap));
String configurationManagerImplTemplate = readResource(
CONFIGURATION_MANAGER_IMPL_SOURCE_TEMPLATE
);
String configurationManagerImplSource = configurationManagerImplTemplate
.replaceAll(CONFIGURATION_CLASS_PACKAGE_VAR, configurationClassPackage)
.replaceAll(CONFIGURATION_CLASS_VAR, configurationClassName);
JavaDynamicBean configurationManagerImplClassBean = new JavaDynamicBean(
CONFIGURATION_MANAGER_IMPL, configurationManagerImplSource);
javaSources.add(configurationManagerImplClassBean);
String configurationManagerTemplate = readResource(CONFIGURATION_MANAGER_SOURCE_TEMPLATE);
String configurationManagerSource = configurationManagerTemplate
.replaceAll(CONFIGURATION_CLASS_PACKAGE_VAR, configurationClassPackage)
.replaceAll(CONFIGURATION_CLASS_VAR, configurationClassName);
JavaDynamicBean configurationManagerClassBean = new JavaDynamicBean(
CONFIGURATION_MANAGER, configurationManagerSource
);
javaSources.add(configurationManagerClassBean);
String configurationListenerTemplate = readResource(CONFIGURATION_LISTENER_SOURCE_TEMPLATE);
String configurationListenerSource = configurationListenerTemplate
.replaceAll(CONFIGURATION_CLASS_PACKAGE_VAR, configurationClassPackage)
.replaceAll(CONFIGURATION_CLASS_VAR, configurationClassName);
JavaDynamicBean configurationListenerClassBean = new JavaDynamicBean(
CONFIGURATION_LISTENER,
configurationListenerSource
);
javaSources.add(configurationListenerClassBean);
String configurationDeserializerSourceTemplate = readResource(
CONFIGURATION_DESERIALIZER_SOURCE_TEMPLATE
);
String configurationDeserializerSource = configurationDeserializerSourceTemplate
.replaceAll(CONFIGURATION_CLASS_PACKAGE_VAR, configurationClassPackage)
.replaceAll(CONFIGURATION_CLASS_VAR, configurationClassName);
JavaDynamicBean configurationDeserializerClassBean = new JavaDynamicBean(
CONFIGURATION_DESERIALIZER,
configurationDeserializerSource
);
javaSources.add(configurationDeserializerClassBean);
String profileClassName = profileSchema.getName();
String profileClassPackage = profileSchema.getNamespace();
if (profileSchemaVersion != DEFAULT_PROFILE_SCHEMA_VERSION) {
javaSources.addAll(generateSchemaSources(profileSchema, uniqueSchemasMap));
}
String profileContainerTemplate = readResource(PROFILE_CONTAINER_SOURCE_TEMPLATE);
String profileContainerSource = profileContainerTemplate
.replaceAll(PROFILE_CLASS_PACKAGE_VAR, profileClassPackage)
.replaceAll(PROFILE_CLASS_VAR, profileClassName);
JavaDynamicBean profileContainerClassBean = new JavaDynamicBean(
PROFILE_CONTAINER, profileContainerSource);
javaSources.add(profileContainerClassBean);
String defaultProfileContainerTemplate = readResource(
DEFAULT_PROFILE_CONTAINER_SOURCE_TEMPLATE);
String defaultProfileContainerSource = defaultProfileContainerTemplate
.replaceAll(PROFILE_CLASS_PACKAGE_VAR, profileClassPackage)
.replaceAll(PROFILE_CLASS_VAR, profileClassName);
JavaDynamicBean defaultProfileContainerClassBean = new JavaDynamicBean(
DEFAULT_PROFILE_CONTAINER, defaultProfileContainerSource);
javaSources.add(defaultProfileContainerClassBean);
String profileSerializerTemplate;
if (profileSchemaVersion == DEFAULT_PROFILE_SCHEMA_VERSION) {
profileSerializerTemplate = readResource(DEFAULT_PROFILE_SERIALIZER_SOURCE_TEMPLATE);
} else {
profileSerializerTemplate = readResource(PROFILE_SERIALIZER_SOURCE_TEMPLATE);
}
String profileSerializerSource = profileSerializerTemplate
.replaceAll(PROFILE_CLASS_PACKAGE_VAR, profileClassPackage)
.replaceAll(PROFILE_CLASS_VAR, profileClassName);
JavaDynamicBean profileSerializerClassBean = new JavaDynamicBean(
PROFILE_SERIALIZER,
profileSerializerSource
);
javaSources.add(profileSerializerClassBean);
String notificationClassName = notificationSchema.getName();
String notificationClassPackage = notificationSchema.getNamespace();
if (notificationSchemaVersion != DEFAULT_SCHEMA_VERSION) {
javaSources.addAll(generateSchemaSources(notificationSchema, uniqueSchemasMap));
}
String notificationListenerTemplate = readResource(NOTIFICATION_LISTENER_SOURCE_TEMPLATE);
String notificationListenerSource = notificationListenerTemplate
.replaceAll(NOTIFICATION_CLASS_PACKAGE_VAR, notificationClassPackage)
.replaceAll(NOTIFICATION_CLASS_VAR, notificationClassName);
JavaDynamicBean notificationListenerClassBean = new JavaDynamicBean(
NOTIFICATION_LISTENER,
notificationListenerSource
);
javaSources.add(notificationListenerClassBean);
String notificationDeserializerSourceTemplate = readResource(
NOTIFICATION_DESERIALIZER_SOURCE_TEMPLATE);
String notificationDeserializerSource = notificationDeserializerSourceTemplate
.replaceAll(NOTIFICATION_CLASS_PACKAGE_VAR, notificationClassPackage)
.replaceAll(NOTIFICATION_CLASS_VAR, notificationClassName);
JavaDynamicBean notificationDeserializerClassBean = new JavaDynamicBean(
NOTIFICATION_DESERIALIZER, notificationDeserializerSource);
javaSources.add(notificationDeserializerClassBean);
if (logSchemaVersion != DEFAULT_SCHEMA_VERSION) {
javaSources.addAll(generateSchemaSources(logSchema, uniqueSchemasMap));
}
String logRecordTemplate = readResource(LOG_RECORD_SOURCE_TEMPLATE);
String logRecordSource = logRecordTemplate
.replaceAll(LOG_RECORD_CLASS_PACKAGE_VAR, logSchema.getNamespace())
.replaceAll(LOG_RECORD_CLASS_VAR, logSchema.getName());
String logCollectorInterfaceTemplate = readResource(LOG_COLLECTOR_INTERFACE_TEMPLATE);
String logCollectorInterface = logCollectorInterfaceTemplate
.replaceAll(LOG_RECORD_CLASS_PACKAGE_VAR, logSchema.getNamespace())
.replaceAll(LOG_RECORD_CLASS_VAR, logSchema.getName());
String logCollectorSourceTemplate = readResource(LOG_COLLECTOR_SOURCE_TEMPLATE);
String logCollectorSource = logCollectorSourceTemplate
.replaceAll(LOG_RECORD_CLASS_PACKAGE_VAR, logSchema.getNamespace())
.replaceAll(LOG_RECORD_CLASS_VAR, logSchema.getName());
JavaDynamicBean logRecordClassBean = new JavaDynamicBean(LOG_RECORD, logRecordSource);
JavaDynamicBean logCollectorInterfaceClassBean = new JavaDynamicBean(
LOG_COLLECTOR_INTERFACE, logCollectorInterface);
JavaDynamicBean logCollectorSourceClassBean = new JavaDynamicBean(
LOG_COLLECTOR_SOURCE, logCollectorSource);
javaSources.add(logRecordClassBean);
javaSources.add(logCollectorInterfaceClassBean);
javaSources.add(logCollectorSourceClassBean);
if (eventFamilies != null && !eventFamilies.isEmpty()) {
for (Schema ctlSchema : eventClassCtlSchemas) {
javaSources.addAll(generateSchemaSources(ctlSchema, uniqueSchemasMap));
}
javaSources.addAll(JavaEventClassesGenerator.generateEventClasses(eventFamilies));
}
String defaultVerifierToken = sdkProfile.getDefaultVerifierToken();
String userVerifierConstantsTemplate = readResource(USER_VERIFIER_CONSTANTS_SOURCE_TEMPLATE);
if (defaultVerifierToken == null) {
defaultVerifierToken = "null";
} else {
defaultVerifierToken = "\"" + defaultVerifierToken + "\"";
}
String userVerifierConstantsSource = userVerifierConstantsTemplate
.replaceAll(DEFAULT_USER_VERIFIER_TOKEN_VAR, defaultVerifierToken);
JavaDynamicBean userVerifierConstantsClassBean = new JavaDynamicBean(
USER_VERIFIER_CONSTANTS, userVerifierConstantsSource);
javaSources.add(userVerifierConstantsClassBean);
String kaaClientTemplate = readResource(KAA_CLIENT_SOURCE_TEMPLATE);
String kaaClientSource = kaaClientTemplate
.replaceAll(LOG_RECORD_CLASS_PACKAGE_VAR, logSchema.getNamespace())
.replaceAll(LOG_RECORD_CLASS_VAR, logSchema.getName())
.replaceAll(CONFIGURATION_CLASS_PACKAGE_VAR, configurationClassPackage)
.replaceAll(CONFIGURATION_CLASS_VAR, configurationClassName);
JavaDynamicBean kaaClientClassBean = new JavaDynamicBean(KAA_CLIENT, kaaClientSource);
javaSources.add(kaaClientClassBean);
String baseKaaClientTemplate = readResource(BASE_KAA_CLIENT_SOURCE_TEMPLATE);
String baseKaaClientSource = baseKaaClientTemplate
.replaceAll(LOG_RECORD_CLASS_PACKAGE_VAR, logSchema.getNamespace())
.replaceAll(LOG_RECORD_CLASS_VAR, logSchema.getName())
.replaceAll(CONFIGURATION_CLASS_PACKAGE_VAR, configurationClassPackage)
.replaceAll(CONFIGURATION_CLASS_VAR, configurationClassName);
JavaDynamicBean baseKaaClientClassBean = new JavaDynamicBean(
BASE_KAA_CLIENT, baseKaaClientSource);
javaSources.add(baseKaaClientClassBean);
packageSources(javaSources, replacementData);
ByteArrayOutputStream sdkOutput = new ByteArrayOutputStream();
ZipOutputStream sdkFile = new ZipOutputStream(sdkOutput);
Enumeration<? extends ZipEntry> entries = templateArhive.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (replacementData.containsKey(entry.getName())) {
ZipEntryData replacementEntry = replacementData.remove(entry.getName());
sdkFile.putNextEntry(replacementEntry.getEntry());
sdkFile.write(replacementEntry.getData());
} else {
sdkFile.putNextEntry(entry);
if (!entry.isDirectory()) {
IOUtils.copy(templateArhive.getInputStream(entry), sdkFile);
}
}
sdkFile.closeEntry();
}
templateArhive.close();
for (String entryName : replacementData.keySet()) {
ZipEntryData replacementEntry = replacementData.get(entryName);
sdkFile.putNextEntry(replacementEntry.getEntry());
sdkFile.write(replacementEntry.getData());
sdkFile.closeEntry();
}
sdkFile.close();
String fileNamePrefix = (sdkPlatform == JAVA ? JAVA_SDK_PREFIX : ANDROID_SDK_PREFIX);
String sdkFileName = fileNamePrefix + sdkProfile.getToken() + ".jar";
byte[] sdkData = sdkOutput.toByteArray();
FileData sdk = new FileData();
sdk.setFileName(sdkFileName);
sdk.setFileData(sdkData);
return sdk;
}
/**
* Package sources.
*
* @param javaSources the java sources
* @param data the data
*/
private void packageSources(List<JavaDynamicBean> javaSources, Map<String, ZipEntryData> data) {
JavaDynamicCompiler dynamicCompiler = new JavaDynamicCompiler();
dynamicCompiler.init();
for (JavaDynamicBean bean : javaSources) {
LOG.debug("Compiling bean [{}]...", bean.getName());
LOG.trace("Bean source:\n{}", bean.getCharContent(true));
Stream<String> sourceLines = Arrays.stream(bean.getCharContent(true).split("\n"));
String packageLine = sourceLines
.filter(line -> line.startsWith("package"))
.findFirst()
.orElse("");
String sourceFileName = packageLine
.replaceAll("package", "")
.replaceAll("\\.|;", "/")
.trim() + bean.getName();
data.put(sourceFileName,
new ZipEntryData(
new ZipEntry(sourceFileName),
bean.getCharContent(true).getBytes()
)
);
}
Collection<JavaDynamicBean> compiledObjects = dynamicCompiler.compile(javaSources,
"-source", JAVA_SOURCE_COMPILER_RELEASE,
"-target", JAVA_TARGET_COMPILER_RELEASE);
for (JavaDynamicBean compiledObject : compiledObjects) {
String className = compiledObject.getName();
String classFileName = className.replace('.', '/') + Kind.CLASS.extension;
ZipEntry classFile = new ZipEntry(classFileName);
ZipEntryData zipEntryData = new ZipEntryData(classFile, compiledObject.getBytes());
data.put(classFileName, zipEntryData);
}
}
/**
* Generate client properties.
*
* @param clientPropertiesStream the client properties stream
* @param bootstrapNodes the bootstrap nodes
* @param configurationProtocolSchemaBody the configuration protocol schema body
* @param defaultConfigurationData the default configuration data
* @return the byte[]
* @throws IOException Signals that an I/O exception has occurred.
*/
private byte[] generateClientProperties(InputStream clientPropertiesStream,
List<BootstrapNodeInfo> bootstrapNodes,
String sdkToken,
String configurationProtocolSchemaBody,
byte[] defaultConfigurationData) throws IOException {
Properties clientProperties = new Properties();
clientProperties.load(clientPropertiesStream);
LOG.debug("[sdk generateClientProperties] bootstrapNodes.size(): {}", bootstrapNodes.size());
clientProperties.put(BUILD_VERSION, Version.PROJECT_VERSION);
clientProperties.put(BUILD_COMMIT_HASH, Version.COMMIT_HASH);
clientProperties.put(BOOTSTRAP_SERVERS_PROPERTY,
CommonSdkUtil.bootstrapNodesToString(bootstrapNodes)
);
clientProperties.put(SDK_TOKEN_PROPERTY, sdkToken);
clientProperties.put(CONFIG_SCHEMA_DEFAULT_PROPERTY, configurationProtocolSchemaBody);
clientProperties.put(CONFIG_DATA_DEFAULT_PROPERTY,
Base64.encodeBase64String(defaultConfigurationData)
);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
clientProperties.store(baos, "");
return baos.toByteArray();
}
}