|
44 | 44 | import java.io.InputStream; |
45 | 45 | import java.io.Serializable; |
46 | 46 | import java.io.UnsupportedEncodingException; |
47 | | -import java.lang.reflect.Method; |
48 | 47 | import java.net.InetAddress; |
49 | | -import java.net.URI; |
50 | | -import java.net.URISyntaxException; |
51 | 48 | import java.net.URLDecoder; |
52 | 49 | import java.text.DateFormat; |
53 | 50 | import java.text.SimpleDateFormat; |
|
83 | 80 | import org.jsoup.Jsoup; |
84 | 81 | import org.jsoup.select.Elements; |
85 | 82 | import org.sakaiproject.authz.api.AuthzRealmLockException; |
86 | | -import org.sakaiproject.authz.api.SecurityAdvisor; |
87 | 83 | import org.sakaiproject.authz.api.SecurityService; |
88 | | -import org.sakaiproject.lti.util.SakaiLTIUtil; |
89 | 84 | import org.sakaiproject.component.cover.ComponentManager; |
90 | 85 | import org.sakaiproject.component.cover.ServerConfigurationService; |
91 | 86 | import org.sakaiproject.content.api.ContentHostingService; |
|
94 | 89 | import org.sakaiproject.entity.api.EntityTransferrer; |
95 | 90 | import org.sakaiproject.entity.api.HttpAccess; |
96 | 91 | import org.sakaiproject.entity.api.Reference; |
97 | | -import org.sakaiproject.entity.api.ResourceProperties; |
98 | 92 | import org.sakaiproject.entity.api.ResourcePropertiesEdit; |
99 | 93 | import org.sakaiproject.entity.cover.EntityManager; |
100 | 94 | import org.sakaiproject.entitybroker.EntityReference; |
|
105 | 99 | import org.sakaiproject.entitybroker.entityprovider.capabilities.Statisticable; |
106 | 100 | import org.sakaiproject.entitybroker.util.AbstractEntityProvider; |
107 | 101 | import org.sakaiproject.exception.IdUnusedException; |
| 102 | +import org.sakaiproject.grading.api.ConflictingAssignmentNameException; |
108 | 103 | import org.sakaiproject.lessonbuildertool.LessonBuilderAccessAPI; |
109 | 104 | import org.sakaiproject.lessonbuildertool.SimplePage; |
110 | 105 | import org.sakaiproject.lessonbuildertool.SimplePageGroup; |
|
120 | 115 | import org.sakaiproject.lessonbuildertool.tool.beans.OrphanPageFinder; |
121 | 116 | import org.sakaiproject.lessonbuildertool.tool.beans.SimplePageBean; |
122 | 117 | import org.sakaiproject.lti.api.LTIService; |
| 118 | +import org.sakaiproject.lti.util.SakaiLTIUtil; |
123 | 119 | import org.sakaiproject.memory.api.MemoryService; |
124 | | -import org.sakaiproject.util.api.LinkMigrationHelper; |
125 | | -import org.sakaiproject.grading.api.ConflictingAssignmentNameException; |
126 | 120 | import org.sakaiproject.site.api.Group; |
127 | 121 | import org.sakaiproject.site.api.Site; |
128 | 122 | import org.sakaiproject.site.api.SitePage; |
|
133 | 127 | import org.sakaiproject.time.api.TimeService; |
134 | 128 | import org.sakaiproject.tool.api.Session; |
135 | 129 | import org.sakaiproject.tool.api.SessionManager; |
136 | | -import org.sakaiproject.tool.api.Tool; |
137 | 130 | import org.sakaiproject.tool.api.ToolManager; |
138 | 131 | import org.sakaiproject.tool.api.ToolSession; |
139 | | -import org.sakaiproject.util.RequestFilter; |
| 132 | +import org.sakaiproject.util.MergeConfig; |
140 | 133 | import org.sakaiproject.util.ResourceLoader; |
141 | 134 | import org.sakaiproject.util.Xml; |
| 135 | +import org.sakaiproject.util.api.LinkMigrationHelper; |
142 | 136 | import org.springframework.context.MessageSource; |
143 | 137 | import org.w3c.dom.Attr; |
144 | 138 | import org.w3c.dom.DOMException; |
|
150 | 144 | import lombok.extern.slf4j.Slf4j; |
151 | 145 | import uk.org.ponder.messageutil.MessageLocator; |
152 | 146 |
|
153 | | -import org.sakaiproject.util.MergeConfig; |
154 | | - |
155 | 147 | /** |
156 | 148 | * @author hedrick |
157 | 149 | * The goal is to get sites to save and copy. However there's actually no data |
@@ -1832,7 +1824,8 @@ public String mergeInternal(String siteId, Element root, String archivePath, Str |
1832 | 1824 | toolsReused.put(title, page.getPageId()); |
1833 | 1825 | reused = true; |
1834 | 1826 | } else { |
1835 | | - page = simplePageToolDao.makePage("0", siteId, title, 0L, 0L); |
| 1827 | + // Create page with initial toolId, parent relationships will be set later |
| 1828 | + page = simplePageToolDao.makePage("0", siteId, title, null, null); |
1836 | 1829 | log.debug("Created new page {}", page.getPageId()); |
1837 | 1830 | } |
1838 | 1831 |
|
@@ -1897,7 +1890,83 @@ public String mergeInternal(String siteId, Element root, String archivePath, Str |
1897 | 1890 | pageElementMap.put(oldPageId, pageElement); |
1898 | 1891 | } |
1899 | 1892 |
|
1900 | | - log.debug("Starting second pass over pages ({}) {} to create items", pageElementMap.size(), pageMap); |
| 1893 | + log.debug("Starting hierarchy calculation for {} pages", pageMap.size()); |
| 1894 | + |
| 1895 | + Map<Long, Long> calculatedParentMap = new HashMap<>(); |
| 1896 | + Map<Long, Long> calculatedTopParentMap = new HashMap<>(); |
| 1897 | + |
| 1898 | + // Get parent-child relationships from source site |
| 1899 | + Map<Long, List<Long>> subpageRefs = findReferencedPagesByItems(fromSiteId); |
| 1900 | + |
| 1901 | + // Build parent map from subpage references |
| 1902 | + for (Map.Entry<Long, List<Long>> entry : subpageRefs.entrySet()) { |
| 1903 | + Long oldParentPageId = entry.getKey(); |
| 1904 | + List<Long> oldChildPageIds = entry.getValue(); |
| 1905 | + |
| 1906 | + if (!pageMap.containsKey(oldParentPageId)) continue; |
| 1907 | + |
| 1908 | + for (Long oldChildPageId : oldChildPageIds) { |
| 1909 | + if (pageMap.containsKey(oldChildPageId)) { |
| 1910 | + calculatedParentMap.put(oldChildPageId, oldParentPageId); |
| 1911 | + } |
| 1912 | + } |
| 1913 | + } |
| 1914 | + |
| 1915 | + // Calculate top parents by walking up the tree |
| 1916 | + for (Long pageId : calculatedParentMap.keySet()) { |
| 1917 | + Long currentPageId = pageId; |
| 1918 | + Long topParent = null; |
| 1919 | + |
| 1920 | + while (calculatedParentMap.containsKey(currentPageId)) { |
| 1921 | + topParent = calculatedParentMap.get(currentPageId); |
| 1922 | + currentPageId = topParent; |
| 1923 | + } |
| 1924 | + |
| 1925 | + if (topParent != null) { |
| 1926 | + calculatedTopParentMap.put(pageId, topParent); |
| 1927 | + } |
| 1928 | + } |
| 1929 | + |
| 1930 | + // Apply calculated relationships to imported pages |
| 1931 | + int hierarchyUpdates = 0; |
| 1932 | + for (Map.Entry<Long, Long> entry : pageMap.entrySet()) { |
| 1933 | + Long oldPageId = entry.getKey(); |
| 1934 | + Long newPageId = entry.getValue(); |
| 1935 | + |
| 1936 | + SimplePage page = simplePageToolDao.getPage(newPageId); |
| 1937 | + if (page == null) continue; |
| 1938 | + |
| 1939 | + boolean updated = false; |
| 1940 | + |
| 1941 | + // Set parent relationship |
| 1942 | + if (calculatedParentMap.containsKey(oldPageId)) { |
| 1943 | + Long oldParentId = calculatedParentMap.get(oldPageId); |
| 1944 | + Long newParentId = pageMap.get(oldParentId); |
| 1945 | + if (newParentId != null) { |
| 1946 | + page.setParent(newParentId); |
| 1947 | + updated = true; |
| 1948 | + } |
| 1949 | + } |
| 1950 | + |
| 1951 | + // Set top parent relationship |
| 1952 | + if (calculatedTopParentMap.containsKey(oldPageId)) { |
| 1953 | + Long oldTopParentId = calculatedTopParentMap.get(oldPageId); |
| 1954 | + Long newTopParentId = pageMap.get(oldTopParentId); |
| 1955 | + if (newTopParentId != null) { |
| 1956 | + page.setTopParent(newTopParentId); |
| 1957 | + updated = true; |
| 1958 | + } |
| 1959 | + } |
| 1960 | + |
| 1961 | + if (updated) { |
| 1962 | + simplePageToolDao.quickUpdate(page); |
| 1963 | + hierarchyUpdates++; |
| 1964 | + } |
| 1965 | + } |
| 1966 | + |
| 1967 | + if (hierarchyUpdates > 0) { |
| 1968 | + log.info("Updated page hierarchies for {} imported pages", hierarchyUpdates); |
| 1969 | + } |
1901 | 1970 |
|
1902 | 1971 | // Process pages we inserted (in PageElementMap) to create the items |
1903 | 1972 | boolean needFix = false; |
@@ -2075,6 +2144,37 @@ public String mergeInternal(String siteId, Element root, String archivePath, Str |
2075 | 2144 | log.debug(result); |
2076 | 2145 | results.append(result); |
2077 | 2146 | } |
| 2147 | + |
| 2148 | + // Update toolIds for child pages |
| 2149 | + int toolIdUpdates = 0; |
| 2150 | + for (Map.Entry<Long, Long> entry : pageMap.entrySet()) { |
| 2151 | + Long oldPageId = entry.getKey(); |
| 2152 | + Long newPageId = entry.getValue(); |
| 2153 | + |
| 2154 | + // Only process child pages (those with topparent) |
| 2155 | + if (calculatedTopParentMap.containsKey(oldPageId)) { |
| 2156 | + Long oldTopParentId = calculatedTopParentMap.get(oldPageId); |
| 2157 | + Long newTopParentId = pageMap.get(oldTopParentId); |
| 2158 | + |
| 2159 | + if (newTopParentId != null) { |
| 2160 | + SimplePage page = simplePageToolDao.getPage(newPageId); |
| 2161 | + SimplePage topParentPage = simplePageToolDao.getPage(newTopParentId); |
| 2162 | + |
| 2163 | + if (page != null && topParentPage != null && topParentPage.getToolId() != null |
| 2164 | + && !topParentPage.getToolId().equals("0") && !topParentPage.getToolId().equals(page.getToolId())) { |
| 2165 | + page.setToolId(topParentPage.getToolId()); |
| 2166 | + simplePageToolDao.quickUpdate(page); |
| 2167 | + toolIdUpdates++; |
| 2168 | + log.debug("Updated toolId {} for page {} from topparent {}", topParentPage.getToolId(), newPageId, newTopParentId); |
| 2169 | + } |
| 2170 | + } |
| 2171 | + } |
| 2172 | + } |
| 2173 | + |
| 2174 | + if (toolIdUpdates > 0) { |
| 2175 | + log.info("Updated toolIds for {} child pages", toolIdUpdates); |
| 2176 | + } |
| 2177 | + |
2078 | 2178 | results.append("merging lessonbuilder tool " + siteId + " (" + count + ") items.\n"); |
2079 | 2179 | } |
2080 | 2180 | catch (DOMException e) |
|
0 commit comments