ATLAS-4652: fix to address potential NPE in AtlasAttributeDef.isSoftReferenced()
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
index a621fb0..bef850c 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
@@ -515,9 +515,9 @@
 
         @JsonIgnore
         public boolean isSoftReferenced() {
-            return this.options != null &&
-                    getOptions().containsKey(AtlasAttributeDef.ATTRDEF_OPTION_SOFT_REFERENCE) &&
-                    getOptions().get(AtlasAttributeDef.ATTRDEF_OPTION_SOFT_REFERENCE).equals(STRING_TRUE);
+            String val = getOption(AtlasAttributeDef.ATTRDEF_OPTION_SOFT_REFERENCE);
+
+            return val != null && Boolean.valueOf(val);
         }
 
         @JsonIgnore
diff --git a/intg/src/main/java/org/apache/atlas/utils/AtlasStringUtil.java b/intg/src/main/java/org/apache/atlas/utils/AtlasStringUtil.java
new file mode 100644
index 0000000..11a4399
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/utils/AtlasStringUtil.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.apache.atlas.utils;
+
+import java.util.Map;
+import java.util.Objects;
+
+public class AtlasStringUtil {
+    public static boolean hasOption(Map<String, String> options, String optionName) {
+        return options != null && options.containsKey(optionName);
+    }
+
+    public static String getOption(Map<String, String> options, String optionName) {
+        return options != null ? options.get(optionName) : null;
+    }
+
+    public static boolean getBooleanOption(Map<String, String> options, String optionName) {
+        return options != null && Boolean.parseBoolean(options.get(optionName));
+    }
+
+    public static boolean getBooleanOption(Map<String, String> options, String optionName, boolean defaultValue) {
+        return (options != null && options.containsKey(optionName)) ? Boolean.parseBoolean(options.get(optionName)) : defaultValue;
+    }
+
+    public static boolean optionEquals(Map<String, String> options, String optionName, String value) {
+        return Objects.equals(options != null ? options.get(optionName) : null, value);
+    }
+}
diff --git a/intg/src/test/java/org/apache/atlas/utils/AtlasStringUtilTest.java b/intg/src/test/java/org/apache/atlas/utils/AtlasStringUtilTest.java
new file mode 100644
index 0000000..da77645
--- /dev/null
+++ b/intg/src/test/java/org/apache/atlas/utils/AtlasStringUtilTest.java
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.apache.atlas.utils;
+
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+public class AtlasStringUtilTest {
+    @Test
+    public void testGetOption() {
+        // null options
+        assertNull(AtlasStringUtil.getOption(null, "opt"));
+
+        // null optionName
+        assertNull(AtlasStringUtil.getOption(Collections.emptyMap(), null));
+
+        // explicit null value for the option
+        assertNull(AtlasStringUtil.getOption(Collections.singletonMap("opt", null), null));
+
+        // option not present
+        assertNull(AtlasStringUtil.getOption(Collections.emptyMap(), "opt"));
+        assertNull(AtlasStringUtil.getOption(Collections.singletonMap("opt", "val"), "opt1"));
+
+        // option present
+        assertEquals(AtlasStringUtil.getOption(Collections.singletonMap("opt", "val"), "opt"), "val");
+        assertNotEquals(AtlasStringUtil.getOption(Collections.singletonMap("opt", "val"), "opt"), "val1");
+    }
+
+    @Test
+    public void testGetBooleanOption() {
+        // null options
+        assertFalse(AtlasStringUtil.getBooleanOption(null, "opt"));
+
+        // null optionName
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), null));
+
+        // explicit null value for the option
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", null), "opt"));
+
+        // option not present
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), "opt"));
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt1"));
+
+        // invalid value for the option
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt"));
+
+        // option present
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "false"), "opt"));
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "true"), "opt"));
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "TRUE"), "opt"));
+    }
+
+    @Test
+    public void testGetBooleanOptionWithDefault() {
+        // null options
+        assertTrue(AtlasStringUtil.getBooleanOption(null, "opt", true));
+        assertFalse(AtlasStringUtil.getBooleanOption(null, "opt", false));
+
+        // null optionName
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), null, true));
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), null, false));
+
+        // explicit null value for the option
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", null), "opt", false));
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", null), "opt", true));
+
+        // option not present
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), "opt", true));
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), "opt", false));
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt1", true));
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt1", false));
+
+        // invalid value for the option
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt", true));
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt", false));
+
+        // valid value for the option
+        assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "false"), "opt", true));
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "true"), "opt", true));
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "TRUE"), "opt", true));
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "true"), "opt", false));
+        assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "TRUE"), "opt", false));
+    }
+
+    @Test
+    public void testOptionEquals() {
+        // null options
+        assertTrue(AtlasStringUtil.optionEquals(null, "opt", null));
+        assertFalse(AtlasStringUtil.optionEquals(null, "opt", "val"));
+
+        // null optionName
+        assertTrue(AtlasStringUtil.optionEquals(Collections.emptyMap(), null, null));
+
+        // explicit null value for the option
+        assertTrue(AtlasStringUtil.optionEquals(Collections.singletonMap("opt", null), "opt", null));
+
+        // option not present
+        assertTrue(AtlasStringUtil.optionEquals(Collections.emptyMap(), "opt", null));
+        assertTrue(AtlasStringUtil.optionEquals(Collections.singletonMap("opt", "val"), "opt1", null));
+
+        // option present
+        assertTrue(AtlasStringUtil.optionEquals(Collections.singletonMap("opt", "val"), "opt", "val"));
+        assertFalse(AtlasStringUtil.optionEquals(Collections.singletonMap("opt", "val"), "opt", "val1"));
+    }
+}
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
index 1d29bf8..ad4672d 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
@@ -34,6 +34,7 @@
 import org.apache.atlas.store.AtlasTypeDefStore;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.utils.AtlasStringUtil;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -106,10 +107,10 @@
 
             RequestContext.get().setImportInProgress(true);
 
-            String transforms = MapUtils.isNotEmpty(request.getOptions()) ? request.getOptions().get(TRANSFORMS_KEY) : null;
+            String transforms = AtlasStringUtil.getOption(request.getOptions(), TRANSFORMS_KEY);
             setImportTransform(source, transforms);
 
-            String transformers = MapUtils.isNotEmpty(request.getOptions()) ? request.getOptions().get(TRANSFORMERS_KEY) : null;
+            String transformers = AtlasStringUtil.getOption(request.getOptions(), TRANSFORMERS_KEY);
             setEntityTransformerHandlers(source, transformers);
 
             startTimestamp = System.currentTimeMillis();
@@ -254,9 +255,8 @@
 
     private EntityImportStream createZipSource(AtlasImportRequest request, InputStream inputStream, String configuredTemporaryDirectory) throws AtlasBaseException {
         try {
-            if (isMigrationMode(request) || (request.getOptions().containsKey(AtlasImportRequest.OPTION_KEY_FORMAT) &&
-                    request.getOptions().get(AtlasImportRequest.OPTION_KEY_FORMAT).equals(AtlasImportRequest.OPTION_KEY_FORMAT_ZIP_DIRECT))) {
-                LOG.info("ZipSource Format: ZipDirect: Size: {}", request.getOptions().get("size"));
+            if (isMigrationMode(request) || AtlasStringUtil.optionEquals(request.getOptions(), AtlasImportRequest.OPTION_KEY_FORMAT, AtlasImportRequest.OPTION_KEY_FORMAT_ZIP_DIRECT)) {
+                LOG.info("ZipSource Format: ZipDirect: Size: {}", AtlasStringUtil.getOption(request.getOptions(), "size"));
                 return getZipDirectEntityImportStream(request, inputStream);
             }
 
@@ -294,6 +294,6 @@
     }
 
     private boolean isMigrationMode(AtlasImportRequest request) {
-        return request.getOptions().containsKey(AtlasImportRequest.OPTION_KEY_MIGRATION);
+        return AtlasStringUtil.hasOption(request.getOptions(), AtlasImportRequest.OPTION_KEY_MIGRATION);
     }
 }
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
index 8e17fd4..0d3e911 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
@@ -36,6 +36,7 @@
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.type.Constants;
+import org.apache.atlas.utils.AtlasStringUtil;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -66,8 +67,7 @@
     public EntityMutationResponse bulkImport(EntityImportStream entityStream, AtlasImportResult importResult) throws AtlasBaseException {
         ImportStrategy importStrategy = null;
 
-        if (importResult.getRequest().getOptions() != null &&
-                importResult.getRequest().getOptions().containsKey(AtlasImportRequest.OPTION_KEY_MIGRATION)) {
+        if (AtlasStringUtil.hasOption(importResult.getRequest().getOptions(), AtlasImportRequest.OPTION_KEY_MIGRATION)) {
             importStrategy = new MigrationImport(this.atlasGraph, new AtlasGraphProvider(), this.typeRegistry);
         } else {
             importStrategy = new RegularImport(this.atlasGraph, this.entityStore, this.typeRegistry);
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/bulkimport/MigrationImport.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/bulkimport/MigrationImport.java
index d6f23d6..f8c9218 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/bulkimport/MigrationImport.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/bulkimport/MigrationImport.java
@@ -39,6 +39,7 @@
 import org.apache.atlas.repository.store.graph.v2.bulkimport.pc.EntityConsumerBuilder;
 import org.apache.atlas.repository.store.graph.v2.bulkimport.pc.EntityCreationManager;
 import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.utils.AtlasStringUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -89,7 +90,7 @@
 
     private DataMigrationStatusService createMigrationStatusService(AtlasImportResult importResult) {
         DataMigrationStatusService dataMigrationStatusService = new DataMigrationStatusService();
-        dataMigrationStatusService.init(importResult.getRequest().getOptions().get(AtlasImportRequest.OPTION_KEY_MIGRATION_FILE_NAME));
+        dataMigrationStatusService.init(AtlasStringUtil.getOption(importResult.getRequest().getOptions(), AtlasImportRequest.OPTION_KEY_MIGRATION_FILE_NAME));
         return dataMigrationStatusService;
     }