Import Routing Profiles Fixes

This commit is contained in:
Nazar 2020-02-10 13:46:57 +02:00
parent 583db6edae
commit 101589e853
8 changed files with 256 additions and 168 deletions

View file

@ -8,7 +8,7 @@
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
<android.support.v7.widget.AppCompatImageView
android:id="@+id/button_icon"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingBottom="@dimen/content_padding_half"
android:paddingTop="@dimen/content_padding_half"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/bottom_sheet_icon_margin"
android:layout_marginRight="@dimen/bottom_sheet_icon_margin"
android:tint="?attr/active_color_basic"
tools:src="@drawable/ic_action_info_dark"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:singleLine="true"
android:textSize="@dimen/default_list_text_size"
android:ellipsize="end"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
osmand:typeface="@string/font_roboto_medium"
android:textColor="?attr/active_color_basic"
tools:text="Title"/>
</LinearLayout>

View file

@ -906,6 +906,7 @@ public class SettingsHelper {
private File file;
private String latestChanges;
private boolean askBeforeImport;
private int version;
private SettingsImportListener listener;
@ -915,11 +916,13 @@ public class SettingsHelper {
private SettingsItem currentItem;
private AlertDialog dialog;
ImportAsyncTask(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) {
ImportAsyncTask(@NonNull File settingsFile, String latestChanges, int version, boolean askBeforeImport,
@Nullable SettingsImportListener listener) {
this.file = settingsFile;
this.listener = listener;
this.latestChanges = latestChanges;
this.version = version;
this.askBeforeImport = askBeforeImport;
importer = new SettingsImporter(app);
}
@ -992,7 +995,7 @@ public class SettingsHelper {
break;
}
} else {
if (item.getType() == SettingsItemType.PROFILE) {
if (item.getType() == SettingsItemType.PROFILE && askBeforeImport) {
String title = activity.getString(R.string.add_new_profile_q, item.getPublicName(app));
dialog = showConfirmDialog(item, title, latestChanges);
} else {
@ -1128,8 +1131,9 @@ public class SettingsHelper {
}
}
public void importSettings(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) {
new ImportAsyncTask(settingsFile, latestChanges, version, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
public void importSettings(@NonNull File settingsFile, String latestChanges, int version,
boolean askBeforeImport, @Nullable SettingsImportListener listener) {
new ImportAsyncTask(settingsFile, latestChanges, version, askBeforeImport, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void exportSettings(@NonNull File fileDir, @NonNull String fileName,

View file

@ -182,7 +182,7 @@ public class ImportHelper {
} else if (fileName != null && fileName.endsWith(IndexConstants.SQLITE_EXT)) {
handleSqliteTileImport(intentUri, fileName);
} else if (fileName != null && fileName.endsWith(OSMAND_SETTINGS_FILE_EXT)) {
handleOsmAndSettingsImport(intentUri, fileName, extras, null);
handleOsmAndSettingsImport(intentUri, fileName, extras, true, null);
} else if (fileName != null && fileName.endsWith(ROUTING_FILE_EXT)) {
handleRoutingFileImport(intentUri, fileName, null);
} else {
@ -606,7 +606,7 @@ public class ImportHelper {
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void chooseFileToImport(final ImportType importType, final CallbackWithObject callback) {
public void chooseFileToImport(final ImportType importType, final boolean askBeforeImport, final CallbackWithObject callback) {
final MapActivity mapActivity = getMapActivity();
if (mapActivity == null) {
return;
@ -644,7 +644,7 @@ public class ImportHelper {
if (fileName.endsWith(importType.getExtension())) {
if (importType.equals(ImportType.SETTINGS)) {
handleOsmAndSettingsImport(data, fileName, resultData.getExtras(), callback);
handleOsmAndSettingsImport(data, fileName, resultData.getExtras(), askBeforeImport, callback);
} else if (importType.equals(ImportType.ROUTING)){
handleRoutingFileImport(data, fileName, callback);
}
@ -733,20 +733,20 @@ public class ImportHelper {
}
}
private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras,
private void handleOsmAndSettingsImport(Uri intentUri, String fileName, Bundle extras, boolean askBeforeImport,
CallbackWithObject<List<SettingsHelper.SettingsItem>> callback) {
if (extras != null && extras.containsKey(SettingsHelper.SETTINGS_VERSION_KEY) && extras.containsKey(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY)) {
int version = extras.getInt(SettingsHelper.SETTINGS_VERSION_KEY, -1);
String latestChanges = extras.getString(SettingsHelper.SETTINGS_LATEST_CHANGES_KEY);
handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, callback);
handleOsmAndSettingsImport(intentUri, fileName, latestChanges, version, askBeforeImport, callback);
} else {
handleOsmAndSettingsImport(intentUri, fileName, null, -1, callback);
handleOsmAndSettingsImport(intentUri, fileName, null, -1, askBeforeImport, callback);
}
}
@SuppressLint("StaticFieldLeak")
private void handleOsmAndSettingsImport(final Uri uri, final String name, final String latestChanges, final int version,
final CallbackWithObject<List<SettingsHelper.SettingsItem>> callback) {
final boolean askBeforeImport, final CallbackWithObject<List<SettingsHelper.SettingsItem>> callback) {
final AsyncTask<Void, Void, String> settingsImportTask = new AsyncTask<Void, Void, String>() {
ProgressDialog progress;
@ -771,7 +771,7 @@ public class ImportHelper {
File tempDir = app.getAppPath(IndexConstants.TEMP_DIR);
File file = new File(tempDir, name);
if (error == null && file.exists()) {
app.getSettingsHelper().importSettings(file, latestChanges, version, new SettingsImportListener() {
app.getSettingsHelper().importSettings(file, latestChanges, version, askBeforeImport, new SettingsImportListener() {
@Override
public void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsHelper.SettingsItem> items) {
if (isActivityNotDestroyed(activity)) {

View file

@ -1,8 +1,9 @@
package net.osmand.plus.profiles;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
public class ProfileDataObject {
public class ProfileDataObject implements Comparable<ProfileDataObject> {
private String name;
private String description;
@ -47,4 +48,9 @@ public class ProfileDataObject {
@ColorRes public int getIconColor(boolean isNightMode) {
return iconColor.getColor(isNightMode);
}
@Override
public int compareTo(@NonNull ProfileDataObject another) {
return this.name.compareToIgnoreCase(another.name);
}
}

View file

@ -1,7 +1,6 @@
package net.osmand.plus.profiles;
import android.app.Activity;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
@ -11,18 +10,20 @@ import android.support.v4.app.FragmentManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import net.osmand.CallbackWithObject;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper.*;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
@ -36,7 +37,6 @@ import java.util.ArrayList;
import java.util.List;
import static net.osmand.plus.helpers.ImportHelper.ImportType.ROUTING;
import static net.osmand.plus.helpers.ImportHelper.ImportType.SETTINGS;
public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialogFragment {
@ -68,14 +68,7 @@ public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialo
if (args != null && args.get(DIALOG_TYPE) != null) {
type = args.getString(DIALOG_TYPE);
selectedItemKey = args.getString(SELECTED_KEY, null);
if (type.equals(TYPE_NAV_PROFILE)) {
profiles.addAll(NavigationFragment.getRoutingProfiles(app).values());
} else if (type.equals(TYPE_BASE_APP_PROFILE)) {
profiles.addAll(NavigationFragment.getBaseProfiles(app));
} else {
LOG.error("Check intent data!");
dismiss();
}
refreshProfiles(app);
}
}
@ -89,22 +82,11 @@ public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialo
dismiss();
}
});
if (type.equals(TYPE_NAV_PROFILE) || type.equals(TYPE_BASE_APP_PROFILE)) {
for (BaseBottomSheetItem item : items) {
View bottomDivider = item.getView().findViewById(R.id.divider_bottom);
if (bottomDivider != null) {
bottomDivider.setVisibility(View.INVISIBLE);
}
}
}
}
@Override
public void createMenuItems(Bundle savedInstanceState) {
int activeColorRes = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
int iconDefaultColorResId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light;
OsmandApplication app = getMyApplication();
OsmandApplication app = requiredMyApplication();
View bottomSpaceView = new View(app);
int space = (int) getResources().getDimension(R.dimen.empty_state_text_button_padding_top);
@ -114,55 +96,20 @@ public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialo
items.add(new TitleItem(getString(R.string.select_base_profile_dialog_title)));
items.add(new LongDescriptionItem(getString(R.string.select_base_profile_dialog_message)));
for (int i = 0; i < profiles.size(); i++) {
final int pos = i;
final ProfileDataObject profile = profiles.get(i);
final boolean isSelected = profile.getStringKey().equals(selectedItemKey);
final Drawable drawableIcon;
if (isSelected) {
drawableIcon = getMyApplication().getUIUtilities()
.getIcon(profile.getIconRes(), activeColorRes);
} else {
drawableIcon = getMyApplication().getUIUtilities()
.getIcon(profile.getIconRes(), R.color.icon_color_default_light);
ProfileDataObject profile = profiles.get(i);
addProfileItem(profile, false);
}
/*items.add(new DividerItem(app));
addButtonItem(R.string.import_from_file, R.drawable.ic_action_folder, new OnClickListener() {
items.add(new BottomSheetItemWithCompoundButton.Builder()
.setCompoundButtonColorId(activeColorRes)
.setChecked(isSelected)
.setButtonTintList(isSelected
? ColorStateList.valueOf(getResolvedColor(getActiveColorId()))
: null)
.setDescription(profile.getDescription())
.setTitle(profile.getName())
.setIcon(drawableIcon)
.setLayoutId(R.layout.bottom_sheet_item_with_descr_and_radio_btn)
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (listener == null) {
getListener();
}
Bundle args = new Bundle();
args.putString(PROFILE_KEY_ARG, profile.getStringKey());
listener.onSelectedType(args);
dismiss();
}
})
.create());
}
items.add(new DividerItem(app));
items.add(new SimpleBottomSheetItem.Builder()
.setTitle(app.getString(R.string.import_from_file))
.setIcon(app.getUIUtilities().getIcon(R.drawable.ic_action_folder, iconDefaultColorResId))
.setLayoutId(R.layout.bottom_sheet_item_simple)
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
MapActivity mapActivity = getMapActivity();
if (mapActivity == null) {
return;
}
mapActivity.getImportHelper().chooseFileToImport(SETTINGS, new CallbackWithObject<List<SettingsItem>>() {
mapActivity.getImportHelper().chooseFileToImport(SETTINGS, false,
new CallbackWithObject<List<SettingsItem>>() {
@Override
public boolean processResult(List<SettingsItem> result) {
for (SettingsItem item : result) {
@ -182,40 +129,81 @@ public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialo
}
});
}
})
.create());
});
items.add(new BaseBottomSheetItem.Builder()
.setCustomView(bottomSpaceView)
.create());
.create());*/
} else if (type.equals(TYPE_NAV_PROFILE)){
} else if (type.equals(TYPE_NAV_PROFILE)) {
items.add(new TitleItem(getString(R.string.select_nav_profile_dialog_title)));
items.add(new LongDescriptionItem(getString(R.string.select_nav_profile_dialog_message)));
for (int i = 0; i < profiles.size(); i++) {
final ProfileDataObject profile = profiles.get(i);
final boolean isSelected = profile.getStringKey().equals(selectedItemKey);
final Drawable drawableIcon;
if (isSelected) {
drawableIcon = getMyApplication().getUIUtilities()
.getIcon(profile.getIconRes(), activeColorRes);
final RoutingProfileDataObject profile = (RoutingProfileDataObject) profiles.get(i);
boolean showBottomDivider = false;
if (i < profiles.size() - 1) {
RoutingProfileDataObject nextProfile = (RoutingProfileDataObject) profiles.get(i + 1);
if (profile.getFileName() == null) {
showBottomDivider = nextProfile.getFileName() != null;
} else {
drawableIcon = getMyApplication().getUIUtilities()
.getIcon(profile.getIconRes(), R.color.icon_color_default_light);
showBottomDivider = !profile.getFileName().equals(nextProfile.getFileName());
}
items.add(new BottomSheetItemWithCompoundButton.Builder()
.setCompoundButtonColorId(activeColorRes)
.setChecked(isSelected)
.setButtonTintList(isSelected
? ColorStateList.valueOf(getResolvedColor(getActiveColorId()))
: null)
.setDescription(profile.getDescription())
.setTitle(profile.getName())
.setIcon(drawableIcon)
.setLayoutId(R.layout.bottom_sheet_item_with_descr_and_radio_btn)
.setOnClickListener(new OnClickListener() {
}
addProfileItem(profile, showBottomDivider);
}
items.add(new DividerItem(app));
items.add(new LongDescriptionItem(app.getString(R.string.osmand_routing_promo)));
addButtonItem(R.string.import_routing_file, R.drawable.ic_action_folder, new OnClickListener() {
@Override
public void onClick(View v) {
MapActivity mapActivity = getMapActivity();
if (mapActivity == null) {
return;
}
mapActivity.getImportHelper().chooseFileToImport(ROUTING, false,
new CallbackWithObject<String>() {
@Override
public boolean processResult(String profileKey) {
refreshView();
return false;
}
});
}
});
items.add(new BaseBottomSheetItem.Builder()
.setCustomView(bottomSpaceView)
.create());
}
}
private void addProfileItem(final ProfileDataObject profile, boolean showBottomDivider) {
OsmandApplication app = requiredMyApplication();
int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
int iconDefaultColorResId = nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light;
View itemView = View.inflate(getContext(), R.layout.bottom_sheet_item_with_descr_and_radio_btn, null);
TextView tvTitle = itemView.findViewById(R.id.title);
TextView tvDescription = itemView.findViewById(R.id.description);
ImageView ivIcon = itemView.findViewById(R.id.icon);
CompoundButton compoundButton = itemView.findViewById(R.id.compound_button);
View bottomDivider = itemView.findViewById(R.id.divider_bottom);
tvTitle.setText(profile.getName());
tvDescription.setText(profile.getDescription());
final boolean isSelected = profile.getStringKey().equals(selectedItemKey);
final Drawable drawableIcon = app.getUIUtilities().getIcon(profile.getIconRes(),
isSelected ? activeColorResId : iconDefaultColorResId);
ivIcon.setImageDrawable(drawableIcon);
compoundButton.setChecked(isSelected);
UiUtilities.setupCompoundButton(compoundButton, nightMode, UiUtilities.CompoundButtonType.GLOBAL);
bottomDivider.setVisibility(showBottomDivider ? View.VISIBLE : View.INVISIBLE);
items.add(new BaseBottomSheetItem.Builder()
.setCustomView(itemView)
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (listener == null) {
getListener();
}
@ -227,40 +215,53 @@ public class SelectProfileBottomSheetDialogFragment extends MenuBottomSheetDialo
})
.create());
}
items.add(new DividerItem(app));
items.add(new LongDescriptionItem(app.getString(R.string.osmand_routing_promo)));
items.add(new SimpleBottomSheetItem.Builder()
.setTitle(app.getString(R.string.import_routing_file))
.setIcon(app.getUIUtilities().getIcon(R.drawable.ic_action_folder, iconDefaultColorResId))
.setLayoutId(R.layout.bottom_sheet_item_simple)
.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
MapActivity mapActivity = getMapActivity();
if (mapActivity == null) {
return;
}
mapActivity.getImportHelper().chooseFileToImport(ROUTING, new CallbackWithObject<String>() {
@Override
public boolean processResult(String profileKey) {
if (listener == null) {
getListener();
}
Bundle args = new Bundle();
args.putString(PROFILE_KEY_ARG, profileKey);
args.putBoolean(IS_PROFILE_IMPORTED_ARG, true);
listener.onSelectedType(args);
dismiss();
return false;
}
});
}
})
.create());
private void addButtonItem(int titleId, int iconId, OnClickListener listener) {
OsmandApplication app = requiredMyApplication();
int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
View buttonView = View.inflate(app, R.layout.bottom_sheet_item_preference_btn, null);
TextView tvTitle = buttonView.findViewById(R.id.title);
tvTitle.setText(app.getString(titleId));
ImageView ivIcon = buttonView.findViewById(R.id.icon);
ivIcon.setImageDrawable(app.getUIUtilities().getIcon(iconId, activeColorResId));
items.add(new BaseBottomSheetItem.Builder()
.setCustomView(bottomSpaceView)
.setCustomView(buttonView)
.setOnClickListener(listener)
.create());
}
private void refreshProfiles(OsmandApplication app) {
if (type.equals(TYPE_NAV_PROFILE)) {
profiles.addAll(NavigationFragment.getSortedRoutingProfiles(app));
} else if (type.equals(TYPE_BASE_APP_PROFILE)) {
profiles.addAll(NavigationFragment.getBaseProfiles(app));
} else {
LOG.error("Check data type!");
dismiss();
}
}
private void refreshView() {
Activity activity = getActivity();
View mainView = getView();
refreshProfiles(getMyApplication());
if (activity != null && mainView != null) {
LinearLayout itemsContainer = (LinearLayout) mainView.findViewById(useScrollableItemsContainer()
? R.id.scrollable_items_container : R.id.non_scrollable_items_container);
if (itemsContainer != null) {
itemsContainer.removeAllViews();
}
items.clear();
createMenuItems(null);
for (BaseBottomSheetItem item : items) {
item.inflate(activity, itemsContainer, nightMode);
}
setupHeightAndBackground(mainView);
}
}
private void getListener() {

View file

@ -125,7 +125,7 @@ public class MainSettingsFragment extends BaseSettingsFragment {
} else if (IMPORT_PROFILE.equals(prefId)) {
final MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
mapActivity.getImportHelper().chooseFileToImport(SETTINGS, new CallbackWithObject<List<SettingsItem>>() {
mapActivity.getImportHelper().chooseFileToImport(SETTINGS, false, new CallbackWithObject<List<SettingsItem>>() {
@Override
public boolean processResult(List<SettingsItem> result) {

View file

@ -22,6 +22,8 @@ import net.osmand.router.GeneralRouter;
import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -36,6 +38,7 @@ public class NavigationFragment extends BaseSettingsFragment {
public static final String TAG = NavigationFragment.class.getSimpleName();
public static final String NAVIGATION_TYPE = "navigation_type";
public static final String OSMAND_NAVIGATION = "osmand_navigation";
private SelectProfileBottomSheetDialogFragment.SelectProfileListener navTypeListener;
private Map<String, RoutingProfileDataObject> routingProfileDataObjects;
@ -163,6 +166,41 @@ public class NavigationFragment extends BaseSettingsFragment {
appMode.setRoutingProfile(profileKey);
}
public static List<RoutingProfileDataObject> getSortedRoutingProfiles(OsmandApplication app) {
List<RoutingProfileDataObject> result = new ArrayList<>();
Map<String, List<RoutingProfileDataObject>> routingProfilesByFileNames = getRoutingProfilesByFileNames(app);
List<String> fileNames = new ArrayList<>(routingProfilesByFileNames.keySet());
Collections.sort(fileNames, new Comparator<String>() {
@Override
public int compare(String s, String t1) {
return s.equals(OSMAND_NAVIGATION) ? -1 : t1.equals(OSMAND_NAVIGATION) ? 1 : s.compareToIgnoreCase(t1);
}
});
for (String fileName : fileNames) {
List<RoutingProfileDataObject> routingProfilesFromFile = routingProfilesByFileNames.get(fileName);
if (routingProfilesFromFile != null) {
Collections.sort(routingProfilesFromFile);
result.addAll(routingProfilesFromFile);
}
}
return result;
}
public static Map<String, List<RoutingProfileDataObject>> getRoutingProfilesByFileNames(OsmandApplication app) {
Map<String, List<RoutingProfileDataObject>> result = new HashMap<>();
for (final RoutingProfileDataObject profile : getRoutingProfiles(app).values()) {
String fileName = profile.getFileName() != null ? profile.getFileName() : OSMAND_NAVIGATION;
if (result.containsKey(fileName)) {
result.get(fileName).add(profile);
} else {
result.put(fileName, new ArrayList<RoutingProfileDataObject>() {
{ add(profile); }
});
}
}
return result;
}
public static Map<String, RoutingProfileDataObject> getRoutingProfiles(OsmandApplication context) {
Map<String, RoutingProfileDataObject> profilesObjects = new HashMap<>();
profilesObjects.put(RoutingProfilesResources.STRAIGHT_LINE_MODE.name(), new RoutingProfileDataObject(