1 //Copyright 2010 Microsoft Corporation 2 // 3 //Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 4 //You may obtain a copy of the License at 5 // 6 //http://www.apache.org/licenses/LICENSE-2.0 7 // 8 //Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an 9 //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 //See the License for the specific language governing permissions and limitations under the License. 11 12 13 namespace System.Data.Services.Common 14 { 15 using System.Collections.Generic; 16 using System.Diagnostics; 17 using System.Linq; 18 using System.Data.Services.Client; 19 20 21 internal sealed class EpmSourceTree 22 { 23 #region Fields 24 25 private readonly EpmSourcePathSegment root; 26 27 private readonly EpmTargetTree epmTargetTree; 28 29 #endregion 30 EpmSourceTree(EpmTargetTree epmTargetTree)31 internal EpmSourceTree(EpmTargetTree epmTargetTree) 32 { 33 this.root = new EpmSourcePathSegment(""); 34 this.epmTargetTree = epmTargetTree; 35 } 36 37 #region Properties 38 39 internal EpmSourcePathSegment Root 40 { 41 get 42 { 43 return this.root; 44 } 45 } 46 47 #endregion 48 Add(EntityPropertyMappingInfo epmInfo)49 internal void Add(EntityPropertyMappingInfo epmInfo) 50 { 51 String sourceName = epmInfo.Attribute.SourcePath; 52 EpmSourcePathSegment currentProperty = this.Root; 53 IList<EpmSourcePathSegment> activeSubProperties = currentProperty.SubProperties; 54 EpmSourcePathSegment foundProperty = null; 55 56 Debug.Assert(!String.IsNullOrEmpty(sourceName), "Must have been validated during EntityPropertyMappingAttribute construction"); 57 foreach (String propertyName in sourceName.Split('/')) 58 { 59 if (propertyName.Length == 0) 60 { 61 throw new InvalidOperationException(Strings.EpmSourceTree_InvalidSourcePath(epmInfo.DefiningType.Name, sourceName)); 62 } 63 64 foundProperty = activeSubProperties.SingleOrDefault(e => e.PropertyName == propertyName); 65 if (foundProperty != null) 66 { 67 currentProperty = foundProperty; 68 } 69 else 70 { 71 currentProperty = new EpmSourcePathSegment(propertyName); 72 activeSubProperties.Add(currentProperty); 73 } 74 75 activeSubProperties = currentProperty.SubProperties; 76 } 77 78 if (foundProperty != null) 79 { 80 Debug.Assert(Object.ReferenceEquals(foundProperty, currentProperty), "currentProperty variable should have been updated already to foundProperty"); 81 82 if (foundProperty.EpmInfo.DefiningType.Name == epmInfo.DefiningType.Name) 83 { 84 throw new InvalidOperationException(Strings.EpmSourceTree_DuplicateEpmAttrsWithSameSourceName(epmInfo.Attribute.SourcePath, epmInfo.DefiningType.Name)); 85 } 86 this.epmTargetTree.Remove(foundProperty.EpmInfo); 87 } 88 89 currentProperty.EpmInfo = epmInfo; 90 this.epmTargetTree.Add(epmInfo); 91 } 92 } 93 }