Đăng ký Đăng nhập
Trang chủ Phát triển cms module cho hệ thống intranet cuả công ty tmareadonly ... primaryi...

Tài liệu Phát triển cms module cho hệ thống intranet cuả công ty tmareadonly ... primaryitem ...

.PDF
42
72
112

Mô tả:

Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA ReadOnly ... PrimaryItem ... SameNameSibs ... ... . (more ChildNodeDefs) . .. PropertyDef Name ... Type ... ValueConstraint ... DefaultValue ... AutoCreate ... Mandatory ... OnParentVersion ... ReadOnly ... PrimaryItem ... Multiple ... . .. . (more PropertyDefs) … 8.2.4.1 Các kiểu node phụ được định nghĩa sẵn Có 2 kiểu node phụ được định nghĩa sẵn là mix:referenceable và mix:versionable trong đó mix:versionable là kiểu node con của mix:referenceable mix:referenceable | |-- mix:versionable Bùi Vĩnh Phú 76 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA Một Node có kiểu là mixin: referenceable được sử dụng cho mục đích : • Nó là đích của thuộc tính có kiểu REFERENCE • Có nhiều hơn một Node cha Một Node có kiểu là mix: versionable dùng cho các Repository có hỗ trợ việc lưu các phiên bản của Node (versioning system). các thuộc tính được quy định bởi kiểu node này đều là các thuộc tính chỉ đọc 8.2.4.2 Các kiểu node chính được định nghĩa sẵn Mọi kiểu node chính đều được bắt nguồn từ kiểu nt:base. Do đó, một Node trên Reporitory ít nhất phải có kiểu node chính nt:base. Kiểu node chính nt:version và nt:versionHistory là cần thiết nếu có sử dụng phiên bản. Cây sau mô tả cấu trúc thừa kế của các kiểu node chính dược định nghĩa sẵn nt:base | |-- nt:default | |-- nt:hierarchyElement | | | |-- nt:file | | | |-- nt:folder |-- nt:nodeType | |-- nt:propertyDef | |-- nt:childNodeDef | |-- nt:versionHistory Bùi Vĩnh Phú 77 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA | |-- nt:version | |-- nt:query 8.3 Node tham chiếu (Referenceable Nodes) Nét đặc biệt của Node tham chiếu là nó được sử dụng trong trường hợp repository có nhiều workspace và việc tạo các phiên bản của node. Một repository có thề có nhiều node tham chiếu, để làm được điều này, nó phải hỗ trợ kiểu mix:refrenceable. Node có kiểu mix:referenceable có một property mang tên jcr:uuid, property này được tạo ra và quản lý bởi hệ thống, client chỉ có thể đọc chứ không thể thay đối hay xóa property này. UUID của một node tham chiếu được ấn định bởi hệ thống trong lúc nó được tạo. Trong một workspace xác định, không tồn tại nhiều hơn một node có chung một UUID. Bùi Vĩnh Phú 78 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA 9. Workspace Như ta đã biết, một repository bao gồm một hay nhiều workspace, mỗi workspace chứa duy nhất một node root. Repository có thể đơn giản, chứa một workspace hay phức tạp, chứa một số lượng lớn workspace. Sau đây là một số mô hình của repository. 9.1 Repository có một workspace Trong trường hợp này repository là một cây gồm các node và property.. Hình 21: Repository có một workspace Bùi Vĩnh Phú 79 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA 9.2 Repository có nhiều Workspace và sự tương ứng các node Trong trường hợp này, một node trong một workspace có thể có các node tương ứng ( corresponding nodes ) trong các workspace khác và chúng cùng chia sẻ một UUID. Các node tương ứng này có thể được xem như là thể hiện của cùng một node trên nhiều workspace khác nhau. Tuy nhiên trong một workspace, không tồn tại 2 node có cùng chung một UUID. Chỉ có các node với kiểu mix:refereneable mới có thể có các node tương ứng trên các workspace khác nhau. Các node tương ứng này chỉ cần có chung một UUID. Do đó chúng có thể có các đường dẫn khác nhau cũng như các property và các node con khác nhau. Khi một node tham chiếu mới (referenceable node) được tạo ra trong workspace bởi hàm Node.addNode thì nó sẽ được ấn định một UUID mới bởi hệ thống. Muốn một node có một node tương ứng trong một workspace khác, nó phải được nhân bản ("cloned") từ workspace nguồn đến workspace đích bằng cách sử dụng phương thức : Workspace.clone( String srcAbsPath, String destAbsPath, String destWorkspace, boolean shallow) Phương thức này thực hiện nhân bản cây con từ đường dẫn srcAbsPath trong workspace nguồn đến đường dẫn destAbsPath trong workspace đích destWorkspace nếu shallow = false, hoặc chỉ nhân bản một node và property của nó nếu shallow= rue. Phương thức clone thực nhân bản cả những node tham chiếu và những node không tham chiếu ( nonreferenceable node ), nhưng chỉ những node tham chiếu mới duy trì mối quan hệ tương ứng của nó giữa các workspace. Bùi Vĩnh Phú 80 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA Trong trường hợp các root node trong các workspace có kiểu là mix:referenceable thì chúng phải có chung một UUID. Root node của một workspace sẽ tự động được tạo ra khi workspace đó được tạo. Biểu đồ sau mô tả một repository có 2 workspace Hình 22: Repository có nhiều workspace Bùi Vĩnh Phú 81 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA Trong biểu đồ trên, repository có 2 workspace là WS1 và WS2. Đường đứt khúc chỉ ra các node có mối quan hệ tương ứng. Trong mỗi workspace có các node không xuất hiện trên workspace còn lại, các node này có thể là các node tham chiếu nhưng không được nhân bản hay các node không tham chiếu. 10. Tạo phiên bản ( Versioning ) Hệ thống tạo phiên bản được xây dựng dựa trên node tham chiếu đã trình bày ở trên. Trong một repository hỗ trợ tạo phiên bản , workspace có thể chứa cả versionable node và nonversionable node. Versionable node có kiểu là mix:versionable. Kiểu mix:versionable là kiểu con thừa kế từ kiểu mix:referenceable, do đó một node cho phép tạo phiên bản thì nó là node tham chiếu và có một UUID. Khả năng có thể tạo phiên bản của node có nghĩa là tại bất kỳ một thời điểm cho trước nào đó, trạng thái của node có thể được lưu giữ để phục vụ cho việc phục hồi trong tương lai. Trạng thái lưu lại này được gọi là một version và hành động lưu lại được gọi là checking in. Version là một phần của version history. Trong một version history, các version hình thành một biểu đồ miêu tả mối quan hệ giữa các versionable node. Các version history lưu trong version storage. Có một version storage trong một repository, nó là một cây con bên dưới node /jcr:versionStorage và được lưu trong mỗi workspace. Bùi Vĩnh Phú 82 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA 10.1 Version History Version History được lưu trong Repository như là một Node có kiểu Node là nt:versionHistory và một Node có kiểu là nt:version sẽ được thêm vào Version History khi một trong những thể hiện của Node trên các Workspace thực hiện thao tác lưu phiên bản (check-in). Khi đó phiên bản mới của Node sẽ được lưu như là thành phần tiếp theo của một hay nhiều phiên bản trước đó (successor). Do đó, Version History sẽ được lưu như là một đồ thị. Hình 23: Đồ thị mô tả một Version History Trong đồ thị dùng để lưu Version History trên thì Node VH có kiểu là nt:versionHistory và Vroot, Va, Vb và Vc có kiểu là nt:version. VH là Node cha của các Node Vroot, Va, Vb và Vc; trong khi Va, Vb là phiên bản kế tiếp của Vroot, tương tự Vc là phiên bản kế tiếp của Va và Vb. Bùi Vĩnh Phú 83 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA Trên Version History luôn có một Node đóng vai trò như là phiên bản ban đầu (Root Version Node). Node này được tạo ra tự động khi Version History mới được tạo ra và đóng vai trò là điểm khởi đầu dùng để duyệt qua hết tất cả các phiên bản khác nằm trên đồ thị biểu diễn Version History. Trong ví dụ trên thì phiên bản ban đầu của Version History VH là Vroot. 10.2 Mối quan hệ giữa các versionable node và version history Mối quan hệ giữa các node và version history được xây dựng trên sự tương ứng thông qua UUID. Các node có chung một UUID sẽ có cùng chung một version history. Trong một workspace chỉ có một versionable node trong một version history Trong một workspace có thể có các version history rỗng. Và các node không có khả năng tạo phiên bản ( nonversionable node ) hiển nhiên không có version history. Khi một versionable node được tạo ra, một version history cho node đó sẽ được tự động tạo ra trong version storage Một versionable node khi được nhân bản sang một workspace khác, node được nhân bản sẽ có chung UUID và chung version history với node gốc. 10.3 Đồ Thị Biểu Diễn Các Phiên Bản Trên Repository Đồ thị dùng để biểu diễn các phiên bản khác nhau của cùng một đối tượng Node trên Repository có cấu trúc cơ bản như sau : • Đồ thị có thể một hay nhiều phiên bản • Đồ thị chỉ có một và chỉ một phiên bản ban đầu (Root Version Node) Bùi Vĩnh Phú 84 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA • Phiên bản ban đầu không có phiên bản trước nó • Những phiên bản không phải phiên bản ban đầu phải có một hoặc nhiều phiên bản trước nó • Mỗi phiên bản có thể có một hoặc nhiều phiên bản sau nó • Mỗi phiên bản không thể là phiên bản trước của chính nó 10.4 Phiên Bản Cơ Bản (Base Version) Các Node có cùng một UUID trên các Workspace khác nhau được xem như là các phiên bản khác nhau của cùng một đối tượng Node trên Repository và các thể hiện này có cùng một Version History. Tuy nhiên, trên Version History có thể có nhiều phiên bản khác nhau và mỗi thể hiện của đối tượng Node có thể chọn cho riêng mình một phiên bản cơ bản khác nhau. Phiên bản cơ bản của một thể hiện dùng để làm phiên bản trước mặc định của một phiên bản mới của thể hiện đó được tạo ra trên Version History. 10.5 Khởi Tạo Một Version History Khi một Node có thể tạo ra phiên bản (Versionable Node) được tạo ra trên Repository thì khi đó một Version History cũng được tạo ra cho Node. Lúc mới tạo ra thì Version History chỉ có một Node có kiểu nt:versionHistory và một Node con có kiểu nt:version đóng vai trò là Root Version. Ví dụ : xét trường hợp một Node N được tạo ra như sau. • Node M là Node cha của Node N và tạo ra Node N bằng cách gọi phương thức M.addNode(“N”). Bùi Vĩnh Phú 85 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA • Trước khi được lưu lại (gọi đến phương thức save) thì Node N được gán thêm loại Node phụ mixin:versionable bằng cách gọi phương thúc N.addMixin(“mix:versionable”). • Khi gọi đến phương thức save của N thì một Version History mới sẽ được tự động tạo ra cho Node N. Điều đó có nghĩa là một Node mới có kiểu nt:versionHistory VH sẽ được tạo ra trên Repository và Node VH này có một Node con có kiểu nt:version V0 gọi là jcr:rootVersion và Node con này chính là Root Version. • Root Version này không chứa trạng thái nào của Node mà nó chỉ chứa thông tin về loại Node và UUID thông qua các thuộc tính jcr:frozenPrimaryType, jcr:frozenMixinType, jcr:frozenUUID của nó. • Giá trị của thuộc tính jcr:versionHistory (thuộc tính này có kiểu REFERENCE) của N được gán bằng với UUID của VH. Điều này cho phép N có thể giữ tham chiếu đến Version History của nó. • Giá trị của thuộc tính jcr:baseVersion (thuộc tính này có kiểu REFERENCE) của N được gán bằng với UUID của V0. Điều này cho. phép N có thể giữ tham chiếu đến Base Version của nó. • Thuộc tính jcr:isCheckedOut của N được gán giá trị true. 10.6 Tạo Phiên Bản Mới Của Một Node Để tạo ra một phiên bản mới của Node lưu trong Version History, cần gọi đến phương thức N.checkin, khi đó sẽ phát sinh một loạt các sự kiện sau. • Một Node mới V có kiểu nt:version sẽ được tạo ra và thêm vào làm Node con của Node VH (Node đại diện cho Version History của N trên Repository và được tham chiếu đến bởi thuộc tính jcr:versionHistory của N). Bùi Vĩnh Phú 86 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA • Base Version B của N (Node được tham chiếu đến bởi thuộc tính jcr:baseVersion của N) được thay đổi bằng cách thêm vào thuộc tính jcr:successor và thuộc tính này giữ tham chiếu đến V vừa mới được thêm vào. • Thuộc tính jcr:baseVersion của N được thay đổi để tham chiếu đến V. • Thuộc tính jcr:isCheckedOut của N được gán giá trị false. • Trạng thái của N được lưu lại trong V bằng cách lưu lại những thông tin của các Node con và thuộc tính của N tuỳ thuộc vào thuộc tính OnParentVersion của các Node con và thuộc tính con này. • Các thuộc tính jcr:primaryType, jcr:mixinTypes và jcr:uuid của N được lưu lại trong V nhưng được đổi tên thành jcr:frozenPrimaryType, jcr:frozenMixinTypes và jcr:frozenUUID để tránh sự trùng tên với những thuộc tính jcr:primaryType, jcr:mixinTypes và jcr:uuid của V. • V được gán một tên, thông thường tên này dựa trên tên của Node trước đó của V. • Nếu nhãn của phiên bản (Version Label) được hỗ trợ khi check-in thì nhãn này sẽ được thêm vào như là một giá trị của thuộc tính đa trị jcr:versionLabels. 10.7 Phục Hồi Lại Trạng Thái Trước Đó Của Node Để phục hồi lại trạng thái trước đó của Node N được lưu trong các phiên bản của nó, chằng hạn xét một phiên bản có tên “x.y” (ta gọi Node tương ứng với phiên bản này là V), cần phải gọi phương thức N.restore(“x.y”). Khi đó, các sự kiện sau sẽ diễn ra. Bùi Vĩnh Phú 87 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA • Các Node con và thuộc tính của N sẽ thay đổi, bị xoá bỏ hay được thêm vào tùy thuộc vào bản sao của các Node con và thuộc tính con này trên V và tuỳ thuộc vào thuộc tính OnParentVersion của từng thành phần con này. • Thuộc tính jcr:baseVersion của N được thay đổi để tham chiếu tới V. • Thuộc tính jcr:isCheckedOut của N được thay đổi thành giá trị false. 10.8 Checkout Thuộc tính jcr:isCheckedOut của một Node N được sử dụng để xác định trạng thái của Base Version hiện tại của Node N là có giống với trạng thái hiện tại của N trên Repository hay không. Sở dĩ có chuyện này do trong quá trình thao tác thì những thay đổi trên Node chỉ có ý nghĩa là thay đổi tạm thời và những thay đổi tạm thời này sẽ được lưu vào Repository khi sự thay đổi đó được lưu thật sự xuống Repository(việc lưu này có thể thông qua nhiều cách khác nhau). Thuộc tính này có giá trị true có nghĩa là 2 trạng thái này không giống nhau và nếu có giá trị false thì có nghĩa là 2 trạng thái này giống nhau. Trạng thái này được xác định thông qua phương thức N.chekout. 10.9 Update Phương thức Node.update(String srcWorkspace, boolean shallow ) sử dụng trong trường hợp repository không hỗ trợ versioning. Node gọi phương thức này sẽ ánh xạ trạng thái của nó sang các node tương ứng trong srcWorkspace. Bùi Vĩnh Phú 88 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA 10.10 Các Node Có Thể Tạo Phiên Bản Trên Repository JCR quy định một Node có thể tạo ra phiên bản của nó trên Repository khi và chỉ khi nó sở hữu kiểu Node phụ mixin:versionable. Những mô tả về kiểu Node phụ này được thể hiện dưới đây : NodeTypeName mix:versionable Supertypes mix:referenceable IsMixin true PropertyDef Name jcr:versionHistory Type REFERENCE ValueConstraint "nt:versionHistory" DefaultValue null AutoCreate true Mandatory true OnParentVersion COPY ReadOnly true PrimaryItem false Multiple false PropertyDef Name jcr:baseVersion Type REFERENCE ValueConstraint "nt:version" DefaultValue null Bùi Vĩnh Phú 89 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA AutoCreate true Mandatory true OnParentVersion IGNORE ReadOnly true PrimaryItem false Multiple false PropertyDef Name jcr:isCheckedOut Type BOOLEAN ValueConstraint null DefaultValue "true" AutoCreate true Mandatory true OnParentVersion IGNORE ReadOnly true PrimaryItem false Multiple false Cũng cần lưu ý là kiểu Node phụ mixin:versionable là kiểu con của kiểu mix:referenceable do đó những Node có kiểu mixin:versionable cũng có UUID. Thêm vào đó, Node có kiểu mixin:versionable còn có thêm các thuộc tính jcr:versionHistory, jcr:baseVersion và jcr:isCheckedOut. Thuộc tính jcr:versionHistory có kiểu thuộc tính là REFERENCE dùng để tham chiếu đến một Version History bằng cách lưu UUID của Version History Node như là giá trị của thuộc tính. Version History này dùng để lưu những phiên bản của Node. Bùi Vĩnh Phú 90 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA jcr:baseVersion có kiểu thuộc tính là REFERENCE dùng để tham chiếu đến một phiên bản trên Version History (Version History này có tham chiếu được lưu trong thuộc tính jcr:versionHistory) bằng cách lưu UUID của Version Node. Version Node này chính là phiên bản cơ bản (Base Version) của Node. jcr:isCheckedOut có kiểu thuộc tính là BOOLEAN dùng để lưu trạng thái của Node và phiên bản với giả trị false cho biết trạng thái hiện tại là check-in và true cho biết trạng thái hiện tại lả check-out. 10.11 Thuộc Tính OnParentVersion Mỗi thành phần (bao gồm Node và các thuộc tính) của một Node có một trạng thái cho biết hành động tương ứng xảy ra đối với Node con hay thuộc tính khi Node cha của nó thực hiện việc tạo ra phiên bản trên Repository. Trạng thái này được xác định bởi thuộc tính OnParentVersion trong PropertyDef hay trong ChildNodeDef được quy định bởi loại Node của Node cha. Xét ví dụ trong đó có Node N là một Node có thể tạo ra phiên bản được (Versionable Node) trên một Workspace W của Repository R. Node N này có loại Node T với T là loại Node con của loại Node nt:versionable và T cho phép N có thuộc tính có tên P và Node con C. các hành động xảy đến cho P và C khi N tạo ra phiên bản trên Repository tùy thuộc vào thuộc tính OnParentVersion trong PropertyDef của P và trong ChildNodeDef của C được quy định bởi T. Các giá trị có thể có của thuộc tính OnParentVersion là • COPY • VERSION Bùi Vĩnh Phú 91 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA • INITIALIZE • COMPUTE • IGNORE • ABORT Các giá trị của thuộc tính OnParentVersion này được quy định như các hằng số trong lớp OnParentVersionAction. javax.jcr.version. OnParentVersionAction int COPY int VERSION int INITIALIZE int COMPUTE int IGNORE int ABORT Bảng 2: Các hằng số trong giao diện javax.jcr.version.OnParentVersionAction 10.11.1 COPY Khi gọi phương thức chekin() của N, C và toàn bộ các thành phần con của nó (bao gồm Node con và các thuộc tính con) sẽ được sao chép vào vùng lưu phiên bản như là cây con của VN. C và các thành phần trong cây con của nó sẽ không có Version History của riêng nó, do đó, C không cần phải là Node có thể tạo phiên bản được (Versionable Node) Bùi Vĩnh Phú 92 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA Khi gọi phương thức restore của N để phục hồi lại trạng thái VN, những bản sao chép của C và cây con của nó đã được lưu trước đó (khi gọi phương thức checkin) cũng sẽ được phục hồi để thay thế C và cây con của nó trên Workspace 10.11.2 VERSION Khi gọi phương thức chekin() của N, VN sẽ thêm vào một tham chiếu đến Version History của C. Do đó, điều này cũng yêu cầu C là một Node có thể tạo ra phiên bản. Nếu C là Node không thể tạo ra phiên bản thì cách xử lý cũng giống như trường hợp IGNORE. Khi gọi phương thức restore của N để phục hồi lại trạng thái VN, nếu trên Workspace hiện thời có sẵn một Node tương ứng với Version History của C thì khi đó thể hiện của C này sẽ trở thành Node con của N. Nếu trên Workspace hiện thời không có Node nào (hay nói chính xác là thể hiện nào) tương ứng với Version History của C thì một phiên bản trên Version History của C sẽ được phục hồi lại như là một Node con của N. Workspace trên đó N được phục hồi sẽ quyết định xem phiên bản nào sẽ được phục hồi và sự quyết định này là do cấu hình của Workspace quy định. 10.11.3 INITIALIZE Khi gọi phương thức chekin() của N, một Node mới của C sẽ được tạo ra và thêm vào vùng lưu phiên bản của Repository như là Node con của VN. Khi Node mới của C được tạo ra thì sự khởi tạo này cũng giống như việc khởi tạo khi C được tạo ra trên Workspace bằng cách thông thường. Node mới của C không có Version History, do đó C cũng không cần phải là một Node có thể tạo phiên bản. Bùi Vĩnh Phú 93 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA Khi gọi phương thức restore của N để phục hồi lại trạng thái VN, Node con C của VN sẽ không được quan tâm, điều đó có nghĩa là Node C hiện tại có trên Workspace sẽ giữ nguyên trạng thái, không bị thay thế bởi Node con C của VN. 10.11.4 COMPUTE Khi gọi phương thức chekin() của N, một Node mới của C sẽ được tạo ra và thêm vào vùng lưu phiên bản của Repository như là Node con của VN. Khi Node mới của C được tạo ra thì sự khởi tạo này được quy định bởi các hàm khởi tạo được định nghĩa bởi loại Node của C. Node mới của C không có Version History, do đó C cũng không cần phải là một Node có thể tạo phiên bản. Khi gọi phương thức restore của N để phục hồi lại trạng thái VN, Node con C của VN sẽ không được quan tâm, điều đó có nghĩa là Node C hiện tại có trên Workspace sẽ giữ nguyên trạng thái, không bị thay thế bởi Node con C của VN. 10.11.5 IGNORE Khi gọi phương thức chekin() của N, không có thông tin nào của C được lưu trong VN. Khi gọi phương thức restore của N để phục hồi lại trạng thái VN, Node con C của N sẽ vẫn giữ nguyên trạng thái hiện tại. 10.11.6 ABORT Khi gọi phương thức chek-in của N thì sẽ phát sinh lỗi (ngoại lệ). Điều này cho thấy khi một Node cha có Node con có thuộc tính OnParentVersion có giá trị FORBIDDEN / ABORT thì Node cha đó sẽ không được quyền check-in. Bùi Vĩnh Phú 94 Đặng Đình Vương Phát triển CMS module cho hệ thống Intranet cuả Công ty TMA 10.12 Ví dụ về một Repository có hỗ trợ tạo phiên bản Hình 24: Repository có nhiều workspace và hỗ trợ tạo phiên bản Bùi Vĩnh Phú 95 Đặng Đình Vương
- Xem thêm -

Tài liệu liên quan